我有由
组成的整数列表{1,2,3,1,2,1,5,1,2,1,1}
我喜欢检索5之前的所有1。我需要在5之后跳过所有其他项目。结束列表将是
{1,1,1}
我如何使用linq做到这一点?
答案 0 :(得分:15)
试试这个:
using System.Linq;
class Program
{
static void Main()
{
var list
= new[] { 1, 2, 3, 1, 2, 1, 5, 1, 2, 1, 1 };
var filteredList
= list.TakeWhile(i => i != 5)
.Where(j => j == 1);
}
}
TakeWhile
方法生成原始序列中的所有元素,直到元素使谓词失败。所以在这种情况下,我们将从list
得到所有数字,直到达到等于5的数字。
完成此操作后,我们只需使用Where
将结果序列过滤到1即可。
答案 1 :(得分:2)
示例显示了Andrew Hare的解决方案与Saeed解决方案之间的懒惰差异。
class Program
{
public static IEnumerable<int> TestData()
{
while (true)
yield return 5;
}
public static IEnumerable<int> AndrewHare(IEnumerable<int> xs)
{
return xs.TakeWhile(i => i != 5)
.Where(j => j == 1);
}
public static IEnumerable<int> Saeed(IEnumerable<int> xs)
{
bool find5 = false;
return xs.Where(p => p == 1 && !(find5 = (p == 5) ? true : find5));
}
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();
watch.Restart();
for (int i = 0; i < 1000000; i++)
{
foreach (var x in AndrewHare(TestData())) ;
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
watch.Restart();
for (int i = 0; i < 1000000; i++)
{
foreach (var x in Saeed(TestData())) ;
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
Console.ReadKey();
}
}