嗨,我有一个多单词字符串的列表。
List<string> myList = new List<string>();
myList.Add("Robert is a bank manager");
myList.Add("Alice is a cashier");
myList.Add("Andrew is bank customer");
Run Code Online (Sandbox Code Playgroud)
现在,对于myList中的每个字符串行,我想获取第n个单词。因此,假设我想从每个字符串中检索偶数个位于数字位置的单词,我希望获得以下输出:
var[] output = {"is", "bank", "is", "cashier", "is", "customer"};
Run Code Online (Sandbox Code Playgroud)
我可以简单地使用for循环并将每个第n个字存储在输出数组中,但很好奇如何使用linq执行相同的操作。
我很好奇如何使用LINQ做同样的事情
给某人一条鱼,然后喂它们一天;教他们抓鱼,等等等等。
您需要的是一个用于LINQ验证代码的思考过程。这是我使用的过程。
我要做的第一件事是查看问题的描述,并认为“ 对序列的每个元素执行的操作在哪里?”
对于myList中的每个字符串行,我想获得第n个字。
哦,有一个。
下一个问题是:假设我想对序列中的单个元素执行此操作;我该怎么办? 我可以写一个做到这一点的方法吗?
这个问题似乎可以很好地分解为两个子问题:
1)给定一个字符串,取回一个单词序列。2)给定一个事物序列,每n个事物产生一个序列。
我们知道如何做第一个:那就是Split()。
第二个是什么?再一次,我们有一个操作,在操作序列中的每个元素。这次我们正在过滤,因此似乎我们想使用Where。
正如其他人指出的那样,您可以Where为此使用一个索引。让我们编写一个辅助方法:
public static IEnumerable<T> TakeEveryNth(
this IEnumerable<T> items,
int n,
int offset = 0) =>
items.Where((item, i) => (i - offset) % n == 0);
Run Code Online (Sandbox Code Playgroud)
(请注意有关此解决方案的一些信息:其中没有特定于字符串序列的内容,因此我将其设为通用。现在,我们有了一个有用的工具,不仅可以用于单词,而且还可以使用。)
超。让我们将最后两个放在一起:
public static IEnumerable<string> EveryNthWord(
this string sentence,
int n,
int offset = 0) =>
sentence.Split(" ").TakeEveryNth(n, offset);
Run Code Online (Sandbox Code Playgroud)
好的,我们要对列表中的每个元素执行此操作,然后将结果全部串联在一起。那是SelectMany。因此,解决您的问题的方法是:
public static IEnumerable<string> EveryNthWord(
this IEnumerable<string> sentences,
int n,
int offset = 0) =>
sentences.SelectMany(sentence => sentence.EveryNthWord(n, offset));
Run Code Online (Sandbox Code Playgroud)
现在,我们可以解决您的问题:
var result = sentences.EveryNthWord(2, 1).ToList();
Run Code Online (Sandbox Code Playgroud)
我们完成了。
这就是您尝试提出LINQ解决方案时要通过问题进行推理的方式:将所有内容分解为小块,并为每个块编写一种可以很好地解决一个问题的方法。 然后将它们与查询运算符结合在一起。
如果我们想将所有这些都变成一个表达式怎么办?如果您已经将其拆分,则这样做会容易得多。 只需将它们组合在一起:
var n = 2;
var offset = 1;
var result = sentences
.SelectMany(sentence => sentence
.Split(" ")
.Where((item, i) => (i - offset) % n == 0))
.ToList();
Run Code Online (Sandbox Code Playgroud)
但是坦率地说,如果将代码分开,代码将更加有用和可读。每种帮助方法都有其自身的用处,因此请保持使用!