C# 實作Javascript “map函數”

map函數 之封面圖

說明:這次主要內容為實作上次所介紹的Javascript的”map函數”功能,我以C#的List陣列擴充了一個Map方法,並使用了多載的方式使參數能像Javascript的map功能任意選填。

實作擴充List陣列程式碼如下:

public static List<T> Map<T>(this List<T> e, Func<T, T> f)
{
 List<T> tmp = new List<T>();
 foreach (var i in e)
  tmp.Add(f(i));
 return tmp;
}

以上程式為單一引數且引數中的函數的引數也是單一的Map多載實作。和Javascript的map功能幾乎一模一樣。

public static List<T> Map<T, U>(this List<T> e, Func<T, U, T> f, U e2)
{
 List<T> tmp = new List<T>();
 foreach (var i in e)
  tmp.Add(f(i,e2));
 return tmp;
}

以上程式為兩個引數且函數的引數也是兩個的Map多載實作,另外因為c#似乎無法像Javascript的apply()函數或是call()函數,可以直接將函數的this指定為該引數的物件,所以我這邊改了一下輸入函數的引數,將輸入函數的引數增加一個在最後面為Map函數的第二個引數的物件。

public static List<T> Map<T>(this List<T> e, Func<T, int, T> f)
{
 List<T> tmp = new List<T>();
 int n = 0;
 foreach (var i in e)
  tmp.Add(f(i, n++));
 return tmp;
}

以上程式為單一引數且引數中的函數的引數是兩個的Map多載實作。輸入的函數的第二個引數和Javascript的map一樣,都是執行的迴圈中當下的索引值,索引值從0開始每圈遞增1。

public static List<T> Map<T, U>(this List<T> e, Func<T, int, U, T> f, U e2)
{
 List<T> tmp = new List<T>();
 int n = 0;
 foreach (var i in e)
  tmp.Add(f(i, n++,e2));
 return tmp;
}

以上程式為兩個引數且引數中的函數的引數是三個的Map多載實作。輸入函數中的第三個引數和上面的程式一樣是Map函數的第二個引數所輸入的參數值。

public static List<T> Map<T>(this List<T> e, Func<T, int, List<T>, T> f)
{
 List<T> tmp = new List<T>();
 int n = 0;
 foreach (var i in e)
  tmp.Add(f(i, n++, e));
 return tmp;
}

以上程式為單一引數且引數中的函數的引數是三個的Map多載實作。輸入的函數的第二個引數同上面輸入的函數是雙引數的狀況,第三個引數和Javascript的map一樣是Map所執行的那個list陣列,也就是this List<T> e的那個e參數。

public static List<T> Map<T, U>(this List<T> e, Func<T, int, List<T>,U, T> f, U e2)
{
 List<T> tmp = new List<T>();
 int n = 0;
  foreach (var i in e)
   tmp.Add(f(i, n++, e,e2));
 return tmp;
}

以上程式為兩個引數且引數中的函數的引數是四個的Map多載實作。輸入的函數的前三個引數和輸入函數為三個引數的前一個多載一樣,最後一個引數和其他Map函數輸入雙引數的狀況一樣。

實際使用範例程式碼:

List<int> data1 = new List<int>() { 1, 2, 3, 4 };
List<int> output = data1.Map(x => x + 1);
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(output));
List<string> data2 = new List<string>() { "Windows 10", "ITE2", "Power", "About" };
List<string> data3 = new List<string>() { "NAS", "Center", "Cloud", "ITE2" };
List<string> output2 = data2.Map(stringadd, data3);
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(output2));
static string stringadd(string a, int b, List<string> c, List<string> d)
{
 return c[b] + " " + d[b];
}

說明:第一行程式宣告了data1變數為int型態的list陣列,並且陣列內容有四筆資料分別為1、2、3、4的數字,第二行程式宣告了output變數為int型態的list陣列並且讓它等於剛才第一行所宣告的data1變數Map(x=>x+1)的結果,x=>x+1相當於f(x) = x+1的函數,所以已Map函數的運作規則data1陣列的第一個陣列變數1輸入f(1) = 1+1會變成2,data1陣列的第二個變數會變成f(2)也就是3,data1陣列的第三個變數會變成f(3)也就是4,data1陣列的第四個變數會變成f(4)也就是5,所以輸出的陣列為[2,3,4,5],output =[2,3,4,5],第三行Newtonsoft.Json.JsonConvert.SerializeObject為Newtonsoft的NuGet套件,可以使用加入NuGet套件來處理JSON相關的資料,Newtonsoft.Json.JsonConvert.SerializeObject主要功能是將物件轉換成JSON的字串,Console.WriteLine主要功能是將引數的內容呈現在console的視窗上,所以console視窗上會顯示[2,3,4,5]的字串,順帶一提因為使用的是WriteLine所以顯示的字串後面會加上換行符號,也就是下一個顯示在console視窗上的資料會在此字串的下一行,第四行程式宣告了data2變數為string型態的list陣列,並且陣列內容有四筆資料分別為”Windows 10“、”ITE2″、”Power”、”About”的字串,第五行程式宣告了data3變數為string型態的list陣列,並且陣列內容有四筆資料分別為”NAS“、”Center”、”Cloud”、”ITE2″的字串,

第六行對data2執行Map函數,引數分別為stringadd這個函數以及data3這個字串陣列,這裡先介紹stringadd這個函數,如第十行所示stringadd函數主要是回傳引數三陣列的第引數二個位置的字串值和空白字符與引數三陣列的第引數二個位置的字串值串接產生的新字串,所以data2.Map(stringadd, data3);會變成data2的第一個陣列值內容”Windows 10“加上空白字元再加上data3的第一個陣列值內容”NAS“也就是”Windows 10 NAS“字串,新產生陣列的第一個陣列值內容,data2的第二個陣列值內容”ITE2″加上空白字元再加上data3的第二個陣列值內容”Center”也就是”ITE2 Center“字串,新產生陣列的第二個陣列值內容,data2的第三個陣列值內容”Power”加上空白字元再加上data3的第三個陣列值內容”Cloud”也就是”Power Cloud“字串,新產生陣列的第三個陣列值內容,data2的第四個陣列值內容”About”加上空白字元再加上data3的第四個陣列值內容”ITE2″也就是”About ITE2“字串,新產生陣列的第四個陣列值內容,第七行將第六行新產生的陣列以JSON字串格式輸出至console視窗顯示,結果為[“Windows 10 NAS“,”ITE2 Center“,”Power Cloud“,”About ITE2“]

Comments

No comments yet. Why don’t you start the discussion?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料