如何使用 LINQ 修改 IEnumerable 以避免 foreach 循环? [复制]

Posted

技术标签:

【中文标题】如何使用 LINQ 修改 IEnumerable 以避免 foreach 循环? [复制]【英文标题】:How to modify IEnumerable with LINQ to avoid foreach loop? [duplicate] 【发布时间】:2020-11-09 09:25:38 【问题描述】:

是否可以在 LINQ 中以单行方式完成以下操作,而不使用 for 循环?

IEnumerable<MyObj> MyList = EF.GetList(etc);
foreach (var row in MyList)

    row.uploadedAt = MyUtils.ConvertToLocalTime(row.uploadedAtUTC, clientTimezone);

//return MyList, which now has both dates in LocalTime and UTC

【问题讨论】:

附加副本有几个解决方案,但使用foreach 进行迭代似乎是最干净的方式。顺便说一句,Linq 没有魔法,它仍然在使用循环 还有 LINQ 方法 ForEach,它的功能与它看起来完全一样 :) 还有 asynchronous version ForEachAsync @MichalTurczyn ForEach 在 LINQ 中吗?我知道没有这种方法。 @mjwills 你是对的。不是 LINQ,List 有 ForEach 方法。 MyList.ToList().ForEach(x=&gt;...) 【参考方案1】:

除了给出的答案之外,还有模仿 foreach 循环的 List&lt;T&gt; 方法 (reference):

EF.GetList(etc).ToList()
    .ForEach(row => row.uploadedAt = MyUtils.ConvertToLocalTime(row.uploadedAtUTC, clientTimezone));

但我没有看到简化事情的任何好处,因为这已经足够简单了。

IMO,过多的简化会导致维护恐惧并降低可读性 :)

【讨论】:

LINQ 没有ForEach。这是List&lt;T&gt; 类的方法。 @JohnWu 谢谢,很好 :) 更正了。【参考方案2】:

重新分配列表,最好不要改变任何东西。这将更符合 LINQ 的functional programming 心态。

IEnumerable<MyObj> myList1 = EF.GetList(etc);
IEnumerable<MyObj> myList2 = myList1.Select( x => 
        new MyObj 
        
            uploadedAt = MyUtils.ConvertToLocalTime(x.uploadedAtUTC, x.clientTimezone),
            anyOtherFields = x.anyOtherFields
        
    ).ToList();

如果构造 MyObj 很复杂和/或您确实需要对其进行变异,您也可以这样做:

IEnumerable<MyObj> myList = EF.GetList(etc);
myList = myList.Select( x => 
        x.uploadedAt = MyUtils.ConvertToLocalTime(x.uploadedAtUTC, x.clientTimezone);
        return x;
    ).ToList();

但如果你打算这样做,你不妨使用for循环。

【讨论】:

你的第二个答案是我自己尝试做的,但被困在返回整个对象(在你的答案中返回 x)。谢谢。

以上是关于如何使用 LINQ 修改 IEnumerable 以避免 foreach 循环? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Ienumerable 和 DB 表之间的 LINQ 内部连接

如何使用 LINQ 从 DataTable 中以 IEnumerable<MODEL> 形式获取数据?

如何在 LINQ 中将 Group By 与 Task<IEnumerable<Entity>> 一起使用

LINQ如何返回IEnumerable 如果接口无法实例化? [重复]

译使用 LINQ 合并 IEnumerable 序列

使用 LINQ 更新 IEnumerable 对象的简单方法