有什么方法可以使用LINQ吗?

时间:2016-03-27 21:09:44

标签: c# .net linq

我有一个foreach循环,我想用LINQ

来做
foreach (int i in indexes)
{
    char[] ch = new char[1];
    input.CopyTo(i, ch, 0, 1);
    chars.Add(ch[0]);
}
  • 索引是整数列表
  • 字符是字符列表
  • 输入是一个字符串

2 个答案:

答案 0 :(得分:8)

让我们看看你的代码是做什么的。

char[] ch = new char[1];
input.CopyTo(i, ch, 0, 1);

这是CopyTo的文档:

  

将此实例中指定位置的指定数量的字符复制到Unicode字符数组中的指定位置。

因此,您始终将字符串的单个字符复制到长度为1的字符缓冲区。特别是对于这种情况,有一种更简单的方法 - 它甚至不涉及临时字符缓冲区:

char ch = input[i];

现在你的下一行变得更加简单:

chars.Add(ch);

所以,总的来说你有这个:

var ch = input[i];
chars.Add(ch);

此变量仅使用一次,显然可以在使用它的位置内联:

chars.Add(input[i]);

因此整个循环变为:

foreach (var i in indexes)
{
    chars.Add(input[i]);
}

这是foreach循环的一个特例,其中每次迭代计算"某些东西" (input[i])并且最后它添加了"某些东西"到集合(chars.Add)。幸运的是,这也是一个非常典型的循环,可以很容易地变成LINQ。

首先,您需要识别,这通常是您在foreach上执行的对象:

indexes

然后,您需要识别选择器,这是计算"某些内容的代码"您正在添加,并将该代码传递给Select方法:

.Select(i => input[i])

此时,你有这个:

indexes.Select(i => input[i]);

您可以按原样将其添加到列表中:

chars.AddRange(indexes.Select(i => input[i]));

但是如果你有特殊情况,列表是空的(例如,因为你刚刚创建它),那么你现在可能正在看这样的事情:

var chars = new List<char>();
chars.AddRange(indexes.Select(i => input[i]));

这也是一种非常常见的情况,ToList()扩展方法可以进一步简化它。该方法基本上枚举了查询并为您创建列表,省去了调用构造函数和AddAddRange方法的麻烦:

var chars = indexes.Select(i => input[i]).ToList();

答案 1 :(得分:3)

chars =
   indexes
   .Select(index => input[index])
   .ToList();

如果其中一个索引超出范围,则会抛出,但原始代码也是如此。此外,如果您需要保留chars中已有的内容,则可能需要连接。