如何将值设置为列表的前N个元素?

时间:2013-12-04 21:12:57

标签: c# linq

给定一个列表我想设置一个值(在我的例子中是红色)到前3个元素;其余元素将有另一种颜色

到目前为止我有这个

int top3=0;
foreach (MyCustomObject gb in Data)
{
    if (top3 <= 3)
    {
        gb.NodeColor = Colors.Green;
    }
    else
    {
        gb.NodeColor = Colors.Red;
    }
    top3++;
}

我不喜欢这种方法,有没有办法用LINQ做到这一点?

Fyi我的列表按升序排序,MyCustomObject不是我班级的真实姓名

6 个答案:

答案 0 :(得分:12)

为什么不只是常规for循环?

for (int i = 0; i < Data.Count(); i++ )
{
    Data[i].NodeColor = (i < 3 ? Colors.Red : Colors.Green);
}

我个人认为这比LINQ更具可读性,但一如既往,您的里程可能会有所不同。

答案 1 :(得分:4)

你可以试试这样的事吗?不太清洁......

    for (int i = 0; i < elementsToSet; i++)
       array[i].NodeColor = Colors.Green;

    for (elementsToSet; elementsToSet < array.Length; elementsToSet++)
       array[elementsToSet].NodeColor = Colors.Red;

编辑:刚刚注意到你想要LINQ ... Woops

答案 2 :(得分:2)

虽然我通常会使用两个for循环,正如前面的回答中提到的,如果真的希望在那里抛出一些,你可以使用一些LINQ:

foreach (var i in Enumerable.Range(0, 3))
    Data[i].NodeColor = Colors.Green;
foreach (var i in Enumerable.Range(3, Data.Length - 3))
    Data[i].NodeColor = Colors.Red;

答案 3 :(得分:1)

您可以使用Select扩展方法的重载来解决它:

var result = Data.Select((x, index) => {
        x.NodeColor = index < 3 ? Colors.Red : Colors.Green;
        return x;
    }).ToArray();

然而,由于它混淆了输入数据的值在选择器函数中被改变的事实,这取决于你是否真的比普通循环更好。因此,克隆数据可能是选择器函数中更好的方法。

答案 4 :(得分:0)

你可以,

int top3 = 3; // Although I think you actually want top4 based on 'i <= 3'
Data.Take(top3).ToList().ForEach(gb => gb.NodeColor = Colors.Green);
Data.Skip(top3).ToList().ForEach(gb => gb.NodeColor = Colors.Red);

虽然在这种情况下,您最终可能会遍历Data来源两次;可能更好的方法是使用for作为@Charlie Kilian提及。

答案 5 :(得分:-1)

由于事实上IEnumerable没有ForEach扩展,因此最好使用for循环。但是如果你真的需要LINQ而不是你需要为IEnumerable实现扩展

    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, 
                                                      Action<T> action){
        foreach (var e in source){
            action(e);
            yield return e;
        }
    }

比你可以在下一个方式使用它

Data.Take(4).ForEach(data=>data.Color=Colors.Red);
Data.Skip(4).ForEach(data=>data.Color=Colors.Green);