c# - 使用 linq 从 C# 列表中的每一行中获取第 n 个单词
问题描述
嗨,我有一个多字串列表。
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");
现在对于 myList 中的每个字符串行,我想得到第 n 个单词。所以假设我想从每个字符串中检索偶数定位的单词,我想得到输出:
var[] output = {"is", "bank", "is", "cashier", "is", "customer"};
我可以简单地使用 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);
(请注意这个解决方案的一些内容:其中没有任何特定于字符串序列的内容,所以我将其设为通用。现在我们有了一个有用的工具,而不仅仅是单词。)
极好的。让我们把最后两个放在一起:
public static IEnumerable<string> EveryNthWord(
this string sentence,
int n,
int offset = 0) =>
sentence.Split(" ").TakeEveryNth(n, offset);
好的,我们想对列表中的每个元素执行此操作,然后将结果连接在一起。那就是SelectMany
。因此,您的问题的解决方案是:
public static IEnumerable<string> EveryNthWord(
this IEnumerable<string> sentences,
int n,
int offset = 0) =>
sentences.SelectMany(sentence => sentence.EveryNthWord(n, offset));
现在我们为您的问题提供了解决方案:
var result = sentences.EveryNthWord(2, 1).ToList();
我们完成了。
当您尝试提出 LINQ 解决方案时,您就是这样解决问题的:将所有内容分解成小块,并为每个小块编写一个可以很好地解决一个问题的方法。 然后将它们与查询运算符组合在一起。
如果我们想把这一切都变成一个表达式怎么办?如果您已经将其分解,那么这样做会容易得多。 只需将它们组合在一起:
var n = 2;
var offset = 1;
var result = sentences
.SelectMany(sentence => sentence
.Split(" ")
.Where((item, i) => (i - offset) % n == 0))
.ToList();
但坦率地说,如果你把它分开,代码会更有用和更易读。每个辅助方法本身都是有用的,所以请保留它们!
推荐阅读
- c# - 如何在 C# 中使用 Azure API 管理中的 SOAP Pass-through 服务
- javascript - 如何对折线点进行网格化?Pathfinding.js 库
- scala - Scala 中 Java 反射的类型安全使用
- html - 我的 CSS 阻止下拉导航栏的引导代码工作
- javascript - 在 Chrome 中为音频启用自动播放策略标志
- javascript - 在 Promise 中获取/捕获响应状态
- ansible - 如果设备位于 PAT 边界之后,则在远程设备和我的 ansible 控制节点之间启动会话的正确语法是什么?
- c# - 无法以一种形式触发要以另一种形式处理的事件
- flutter - 为什么从共享偏好中获取数据会有延迟?
- ruby - 如何按外键分组和求和?