简单的传统foreach到Linq ForEach

时间:2016-08-22 11:10:12

标签: c# linq foreach

我有一个字符串列表,如:

abcd@domain.com
efgh@domain.com
ijkl@domain.com;mnop@domain.com;qrst@domain.com
uvwx@domain.com
yz@domain.com

我想要它:

abcd@domain.com
efgh@domain.com
ijkl@domain.com
mnop@domain.com
qrst@domain.com
uvwx@domain.com
yz@domain.com

所以我编写了下面的代码,它按预期工作。

foreach (var email in emailAddressesOnRequest)
{
    if (!string.IsNullOrEmpty(email) && email.Contains(';'))
    {
        emailAddressesOnRequest.AddRange(email.Split(';').ToList());
        emailAddressesOnRequest.Remove(email);
    }
}

有没有办法将它简单地用于LINQ ForEach?

3 个答案:

答案 0 :(得分:5)

您正在寻找的是遍历集合,并为每个项目返回不同类型的项目。为此使用Select

因为在您的情况下,您可能希望从每个项目中返回项目集合,并且不希望在嵌套集合中使用SelectMany方法的结果使用Split(';')

List<string> values = new List<string>
{
    "abcd@domain.com",
    "efgh@domain.com",
    null,
    "ijkl@domain.com; mnop @domain.com; qrst @domain.com",
    "uvwx@domain.com",
    "yz@domain.com"
};

var result = values.Where(value => !string.IsNullOrWhiteSpace(value))
                   .SelectMany(value => value.Split(';')).ToList();

在查询语法中:

var result = (from value in values
             where !string.IsNullOrWhiteSpace(value)
             from email in value.Split(';')
             select email).ToList();

答案 1 :(得分:1)

var query = from line in emailAddressesOnRequest
            where !String.IsNullOrEmpty(line)
            from email in line.Split(';')
            select email;

答案 2 :(得分:1)

帮助我理解灵的原因是The standard LINQ operators

如果您通过分号将每个字符串拆分为子字符串,则会得到字符串序列的集合,或者IEnumerable<IEnumerable<string>>

IEnumareable转换为IEnumerable<string>的{​​{1}}扩展功能为Enumerable.SelectMany。迭代SelectMany就像你做一个嵌套的foreach:

List<string[]> listOfStringArrays = ...
List<string> outputList = new List<string>();
foreach (string[] stringArray in listOfStringArrays)
{
     foreach (string str in stringArray)
     {
         outputList.Add(str);
     }
}

在您的示例中,内部foreach使用AddRange完成。

使用SelectSplit将字符串集合转换为字符串序列序列。 SelectMany会使它成为一系列字符串:

IEnumerable<string> myInputStrings = ...
IEnumerable<string> outputStrings = inputStrings
    .Select(inputString => inputString.Split(';'))
    .SelectMany(splitResult => splitResult);

Select将获取每个inputStrings,并以分号分隔。输出是一个字符串数组,即使您的输入没有分号,也会实现IEnumerable<string>

SelectMany连接字符串序列序列的每个字符串序列。结果是一个字符串序列。

要转换为数组或列表,请使用ToArray()ToList()