Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用LINQ查询替换foreach_C#_.net_Linq - Fatal编程技术网

C# 用LINQ查询替换foreach

C# 用LINQ查询替换foreach,c#,.net,linq,C#,.net,Linq,我的一个方法中包含以下代码: foreach (var s in vars) { foreach (var type in statusList) { if (type.Id == s) { Add(new NameValuePair(type.Id, type.Text)); break; } } } 这对我来说似乎有点无效,我想知道是否有一种方法可以用LINQ查询替换至少

我的一个方法中包含以下代码:

foreach (var s in vars)
{
    foreach (var type in statusList)
    {
        if (type.Id == s)
        {
            Add(new NameValuePair(type.Id, type.Text));
            break;
        }
    }
}
这对我来说似乎有点无效,我想知道是否有一种方法可以用LINQ查询替换至少一个foreaches。有什么建议吗

编辑:vars是一个字符串数组,Add方法向CSLA NameValueList中添加一项。

类似以下内容:

foreach(var s in vars) {
    var type = statusList.FirstOrDefault(t => t.Id == s);
    if (type != null)
        Add(new NameValuePair(type.Id, type.Text));
}
或者,如果vars支持
ForEach
方法,这也会起作用(但是我建议不要过度使用):

我假设
类型
是引用类型的一个实例。

基本上:

var types =
    from s in vars
    let type = (
        from tp in statusList
        where tp.Id == s ).FirstOrDefault()
    where type != null
    select new NameValuePair(type.Id, type.Text)

具有IEnumerable的扩展ForEach的实现。

编辑:我没有注意到
中断之前

如果可能有多个具有相关ID的类型,则需要根据下面的或我的第二个代码示例使用
FirstOrDefault

编辑:删除“multi-from”版本,因为假设equality/hashcode适用于
type.Id
的任何类型,这是不必要的低效

不过,联接可能更合适:

var query = from s in vars
            join type in statusList on s equals type.Id
            select new NameValuePair(type.Id, type.Text);

foreach (var pair in query)
{
    Add(pair);
}
您可能希望创建一个
AddRange
方法,该方法采用
IEnumerable
,此时您可以调用
AddRange(query)

或者,您可以使用查找。此版本确保每个“s”只添加一种类型


这样做的好处是,基本上只需遍历一次类型列表即可建立字典。

如果Add方法正在构建列表,您还可以尝试:

IEnumarable<NamedValuePair> result = statusList.Where(type => type.Id == s).Select(new NameValuePair(type => type.Id, type.Text));
IEnumarable result=statusList.Where(type=>type.Id==s)。选择(newnameValuePair(type=>type.Id,type.Text));

我看不到关于群组加入的答案,所以这里有一个:

var result = vars
  .GroupJoin
  (
    statusList,
    s => s,
    type => type.Id,
    (s, g) => g.Any() ? g.First() : null
  )
  .Where(type => type != null)
  .Select(type => new NameValuePair(type.Id, type.Text));

我看不出这是如何编译的——在第三行中使用“type”是行不通的,因为变量没有在任何地方声明。“任何”呼叫中的lambda表达式不会持续。Jon,感谢您的注意!我仍然在想我是怎么犯了那个愚蠢的错误的。中断只意味着第一个匹配,其中'type.Id=s',你的解决方案匹配内部可枚举中的所有情况。因此以“如果可能…”开头的句子:)是的,我也应该在发布相同的答案之前向下滚动:)今天的课程:更仔细地阅读。
IEnumarable<NamedValuePair> result = statusList.Where(type => type.Id == s).Select(new NameValuePair(type => type.Id, type.Text));
var result = vars
  .GroupJoin
  (
    statusList,
    s => s,
    type => type.Id,
    (s, g) => g.Any() ? g.First() : null
  )
  .Where(type => type != null)
  .Select(type => new NameValuePair(type.Id, type.Text));