iT邦幫忙

1

使用Lambda替換For迴圈

c#
deh 2019-12-12 13:16:322179 瀏覽
  • 分享至 

  • xImage

目標是輸入任意英文文章後,可計算出各字母出現了幾次。
下面是我用For迴圈的做法,想請問改成用Lambda的話可以精簡到怎樣?

//前置作業開始
            //txt為隨意輸入的英文文章
            string txt = "Property is used to gets or sets the element at the specified index. Properties of List: It is different from the arrays. ";
            //過濾用
            string[] words = txt.Split(' ',',','.','!','?',':');
            List<string> cleanTxt = new List<string>();
            //全轉為小寫
            foreach (string word in words)
            {
                if (word != "") { 
                    cleanTxt.Add(word.ToLower());
                }
            }
            System.Console.WriteLine("---------");
            //前置作業結束

            //分別儲存英文單字與出現次數
            List<string> targetWord = new List<string>();
            int[] targetWordnum = new int[cleanTxt.Count];
            //進迴圈判斷
            for (int i = 0, j = 0; i < cleanTxt.Count; i++) {
                if (!targetWord.Contains(cleanTxt[i])) {
                    targetWord.Add(cleanTxt[i]);
                    targetWordnum[j] = 1;
                    j += 1;
                } else {
                    int k = targetWord.IndexOf(cleanTxt[i]);
                    targetWordnum[k] += 1;
                    //System.Console.WriteLine($"{cleanTxt[i]}:{targetWordnum[k]}");
                }
            }

            //畫面輸出結果
            System.Console.WriteLine("---------");
            for (int i = 0; i < targetWord.Count; i++) {
                System.Console.WriteLine($"{targetWord[i]}:{targetWordnum[i]}");
            }
看更多先前的討論...收起先前的討論...
fillano iT邦超人 1 級 ‧ 2019-12-12 14:29:15 檢舉
Lambda跟精簡沒那麼直接關係吧,該寫的程式還是得寫
都用 LINQ ~~~

string txt = "Property is used to gets or sets the element at the specified index. Properties of List: It is different from the arrays. ";

var rlt = new Dictionary<string, int>();
txt.Split(' ', ',', '.', '!', '?', ':')
.Where(it => it != "")
.Select(it => it.ToLower())
.ToList()
.ForEach(it =>
{
if (!rlt.ContainsKey(it))
rlt.Add(it, 0);
rlt[it]++;
});

rlt.ToList()
.ForEach(it => Console.WriteLine($"{it.Key}:{it.Value}"));
deh iT邦研究生 1 級 ‧ 2019-12-12 15:02:24 檢舉
個人對Lambda不熟悉,主管說我迴圈的東西用Lambda一行就夠了,但自己想半天不知道怎樣達成,所以上來討教
deh iT邦研究生 1 級 ‧ 2019-12-12 15:03:01 檢舉
用 LINQ十分清楚,我再熟悉一下,感謝你
deh iT邦研究生 1 級 ‧ 2019-12-12 15:36:51 檢舉
剛剛主管表示var words = txt.Split(' ', ',', '.', '!', '?', ':').GroupBy(key => key).ToDictionary(k => k.Key, value => value.Count());
用 GroupBy 好精簡,主管大大厲害
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

7
石頭
iT邦高手 1 級 ‧ 2019-12-12 14:26:03
最佳解答

Spilt完後可以使用where,select,String.Join組成一個字串.

在用GroupBy來做分群

string txt = "Property is used to gets or sets the element at the specified index. Properties of List: It is different from the arrays. ";

var words = txt.Split(' ',',','.','!','?',':')
			   .Where(s=>!string.IsNullOrEmpty(s))
			   .Select(x=>x.ToLower());

var wordLine = string.Join("", words);

var result = wordLine.GroupBy(x => x).Select(x => new {word = x.Key, Count = x.Count()});

foreach (var item in result)
{
	Console.WriteLine($"{item.word}:{item.Count}");
}
米歐 iT邦新手 3 級 ‧ 2019-12-12 14:28:32 檢舉

切割完不用組回去就能直接用吧

deh iT邦研究生 1 級 ‧ 2019-12-12 15:18:56 檢舉

十分感謝
(我原本問題寫字母,code寫單字,寫錯了orz,不過本質上是一樣的東西)

8
YoChen
iT邦研究生 1 級 ‧ 2019-12-12 14:34:01

您可能要先解決資料結構的問題,再來考慮怎麼改成用Lambda Function來做,像這種很明顯有Key/Value Pair的型態,基本上就可以直接用Dictionary來做,改完就會發現根本沒有改寫Lambda的必要~XDDD
e.g.

string txt = "Property is used to gets or sets the element at the specified index. Properties of List: It is different from the arrays. ";
char[] splitChar = { ' ', ',', '.', '!', '?', ':' };
string[] words = txt.Split(splitChar, StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, int> wordsDict = new Dictionary<string, int>();

for (int i = 0; i < words.Length; i++)
{
    string word = words[i].ToLower();

    if (!wordsDict.ContainsKey(word))
    {
        wordsDict.Add(word, 1);
    }
    else
    {
        wordsDict[word] += 1;
    }
}

var dictEnum = wordsDict.AsEnumerable(); // Enum化,方便列舉輸出

foreach (var item in dictEnum)
{
    // 輸出
    Console.WriteLine($"{item.Key}:{item.Value}");
}

Console.ReadKey();
deh iT邦研究生 1 級 ‧ 2019-12-12 15:23:27 檢舉

Lambda一行寫完感覺比較厲害(?

YoChen iT邦研究生 1 級 ‧ 2019-12-12 15:57:07 檢舉

本質上都是要先整理再輸出啦~XDDD
但我自己偏好讓程式看起來好讀一點,以後比較不會看不懂,當然也有可能是我程度還不到,沒辦法馬上讀懂~
/images/emoticon/emoticon06.gif

我要發表回答

立即登入回答