【问题标题】:Convert loop to LINQ将循环转换为 LINQ
【发布时间】:2012-11-05 22:20:52
【问题描述】:

计算每日回报的 Equity Analytics(股票)对象列表。 正在考虑必须有一个成对的解决方案来做到这一点:

for(int i = 0; i < sdata.Count; i++){
    sdata[i].DailyReturn = (i > 0) ? (sdata[i-1].AdjClose/sdata[i].AdjClose) - 1
                                   : 0.0;
}

【问题讨论】:

  • 我不知道,你在做基于 sdata[i-1] 的逻辑似乎很难做一个 linq 查询来模拟它
  • 为什么要把它转换成 Linq。酷吗?
  • @L.B.林克!!!!!!我必须拥有其中之一!林克!天哪!

标签: c# linq list


【解决方案1】:

LINQ 代表:“语言集成查询

LINQ 不应该使用并且几乎不能用于赋值,LINQ 不会更改给定的 IEnumerable 参数,而是创建一个新参数。

正如下面评论中所建议的,有一种方法可以使用 LINQ创建一个新的 IEnumerable,它会更慢,而且可读性也会差很多。

虽然 LINQ 很好,但重要的是要知道什么时候不使用它。

只需使用旧的 for 循环

【讨论】:

  • 这不是真的。 IEnumerable 存在一个扩展,它还允许您使用索引。尴尬来自于这样一个事实,即每次迭代执行的操作都是一个赋值。
  • @DoomMuffins。他需要Foreach,然后获取每个元素的索引,你说得对,我不够清楚。
  • @L.B.在没有ForEach 的情况下不知道如何更改sdata IEnumerable。 Select 创建一个新的 IEnumerable,而不是修改现有的。
  • enumerable.Select((item, index) =&gt; { sdata[index].DailyReturn = something; return anothething; });当然很丑……
  • @gdoron 代码将按原样保留在生产环境中,或者至少作为 for 循环。只是想探索一下可能性,伤害在哪里?
【解决方案2】:

我是 LINQ 的新手,我开始使用它是因为 stackoverflow,所以我尝试解决您的问题,我知道这可能会吸引反对票,但我尝试过,它可以满足您的要求,以防至少有一个元素在列表中。

sdata[0].DailyReturn = 0.0;
sdata.GetRange(1, sdata.Count - 1).ForEach(c => c.DailyReturn = (sdata[sdata.IndexOf(c)-1].AdjClose / c.AdjClose) - 1);

但必须说避免 for 循环不是最佳做法。从我的角度来看,LINQ 应该在方便的地方使用,而不是无处不在。好的旧循环有时更容易维护。

【讨论】:

  • GetRange: 在源列表中创建一系列元素的浅表副本它不会更改列表,与 for 循环不同。
  • 所有注意事项都是很好的建议,但这更多的是学习。当然有一些函数式语言可以更有效地实现类似的方法,比如 F#。不更改列表而是创建一个新列表是功能性方式。
  • 嗯,我不知道你为什么还要创建一个新列表。这是 c#,它不起作用。保持循环,这就是它应该实现的方式。
  • 见上文坚持使用原始码。对于 c# 不具备功能性,请有所不同,任何语言都可以具备功能性,而 c# 已经添加了功能来促进这一点。
  • 正在寻找更像这样的东西:TS answer to how get pairs in a list
猜你喜欢
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-16
  • 2014-03-12
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多