现在,我有2个列表(_pumpOneSpm和_pumpTwoSpm),它们是数据库查询的结果。现在,我一直在使用LINQ填充列表供我进行计算。类似的东西:
var spmOne = _pumpOneSpm.Where((t, i) => _date[i].Equals(date) &&
DateTime.Compare(_time[i], DateTime.Parse(start)) > 0 &&
DateTime.Compare(_time[i], DateTime.Parse(end)) < 0).ToList();
这很好,因为我一直在从一个列表中提取数据,以将特定数据添加到另一个列表中。但现在,我需要从两个列表中提取数据以添加到一个列表中。我很好奇是否有办法用LINQ做这个,或者我应该用for循环迭代?这是我用for循环得到的:
for (var i = 0; i < _pumpOneSpm.Count; i++)
{
if (_date[i].Equals(date))
{
if (DateTime.Compare(_time[i], DateTime.Parse(start)) > 0)
{
if (DateTime.Compare(_time[i], DateTime.Parse(end)) < 0)
{
spmOne.Add(_pumpOneSpm[i]);
spmOne.Add(_pumpTwoSpm[i]);
}
}
}
}
这有效,并且做我想要的。但我只是想让它更高效,更快。我可以为每个列表使用类似于第一个代码块的两行,但这意味着我要迭代两次。因此,重申一下我的问题,是否可以使用LINQ命令同时从两个列表中提取数据以填充另一个列表,或者我应该坚持使用for循环?感谢您的帮助。
修改
我没有提到,使用这些步骤的功能的目的是精确_pumpOneSpm&amp;的MAX。 _pumpTwoSpm。不是每个的最大值,而是它们之间的最大值。因此,最初我将它们添加到一个列表中,只是调用spmOne.Max()。但是有两个像上面这样的LINQ查询,我正在运行一个if语句来比较两个maxes,然后返回两个中的较大者。因此,从技术上讲,他们不需要在一个列表中,我只是认为如果它们更容易处理。
答案 0 :(得分:2)
因此,重申我的问题,是否可以使用LINQ命令 同时从两个列表中提取数据以填充另一个列表,或 我应该坚持使用我的for循环吗?
合并列表:
var mergedList = list1.Union(list2).ToList();
如果需要,可以选择,然后过滤:
var filtered = mergedList.Where( p => ... filter ... );
对于Max:
var max = filtered.Max();
注:
OP表示没有必要从订单到非重复,所以Union会好的。
答案 1 :(得分:2)
所以最简单的方法就是这样:
var resultList = list1.Concat(list2).ToList();
请注意,这与你的for循环略有不同(项目的顺序不一样)。它将包含一个列表中的所有项目,然后是来自另一个列表的所有项目,而不是第一个中的第一个,第二个中的第一个,等等。如果这很重要,您仍然可以使用LINQ,但需要额外的一些方法调用。
你提到了表现;值得注意的是,与for
循环相比,你不会明显改善性能。你可以获得更短的代码;代码更具可读性,并且将执行相同的。就运行速度而言,根本没有足够的空间来改进。
值得注意的是,你可以结合这两种方法;这甚至不是一个坏主意。您可以使用LINQ过滤两个输入序列(使用Where
),然后foreach
过滤结果,将它们添加到列表中(或使用AddRange
)。
var query1 = _pumpOneSpm.Where((t, i) => _date[i].Equals(date) &&
DateTime.Compare(_time[i], DateTime.Parse(start)) > 0 &&
DateTime.Compare(_time[i], DateTime.Parse(end)) < 0);
var query2 = ...
List<T> results = new List<T>(query1);
results.AddRange(query2);
答案 2 :(得分:0)
您可以使用SelectMany方法
答案 3 :(得分:0)
您可以使用Enumerable.Range实现与for循环类似的功能。 SelectMany然后允许您在每次迭代时添加多个项目,然后展平生成的序列。
spmOne = Enumerable
.Range(0, _pumpOneSpm.Count)
.Where(index => _date[index].Equals(date) &&
DateTime.Compare(_time[index], DateTime.Parse(start)) > 0 &&
DateTime.Compare(_time[index], DateTime.Parse(end)) < 0)
.SelectMany(index => new [] { _pumpOneSpm[index], _pumpTwoSpm[index] })
.ToList();
以下是查询语法版本:
spmOne = (from index in Enumerable.Range(0, _pumpOneSpm.Count)
where _date[index].Equals(date) &&
DateTime.Compare(_time[index], DateTime.Parse(start)) > 0 &&
DateTime.Compare(_time[index], DateTime.Parse(end)) < 0
from pumpSpm in new [] { _pumpOneSpm[index], _pumpTwoSpm[index] }
select pumpSpm).ToList();
答案 4 :(得分:0)
如果您想避免使用索引,可以Zip一起使用。
spmOne = _pumpOneSpm
.Zip(_pumpTwoSpm, (pump1, pump2) => new { pump1, pump2 } )
.Zip(_date, (x, pumpDate) => new { x.pump1, x.pump2, date = pumpDate })
.Zip(_time, (x, time) => new { x.pump1, x.pump2, x.date, time })
.Where(x => x.date.Equals(date) &&
DateTime.Compare(x.time, DateTime.Parse(start)) > 0 &&
DateTime.Compare(x.time, DateTime.Parse(end)) < 0)
.SelectMany(x => new [] { x.pump1, x.pump2 })
.ToList();
功能上存在一个小的差异:如果任何序列短于_pumpOneSpm
,则生成的序列将是最短序列的长度,并且对于超出范围的索引不会抛出异常。