最简单的方法是根据属性值将对象放入单独的列表中

时间:2009-04-28 21:39:52

标签: c# .net linq

我有一组对象,我很好奇你将它们分成两个列表的方式 - 一个列表将包含特定类型的所有内容,另一个列表将包含其余内容。我想到的一种方法是:

var typeXs = (from o in collectionOfThings where o.Type == "typeX" select o);
var notTypeXs = (from o in collectionOfThings where o.Type != "typeX" select o);

另一种方法是循环遍历collectionOfThings并根据if / else分配。

这两种方式都很简单,可读,但我只是想知道是否有更流畅的方式?

6 个答案:

答案 0 :(得分:4)

这个例子应该展示你的目标:

class MyObject
{
    public int n;
    public string t;
}

加载我的原始列表:

List<MyObject> allObjects = new List<MyObject>() {
    new MyObject() { n = 0, t = "x" },
    new MyObject() { n = 1, t = "y" },
    new MyObject() { n = 2, t = "x" },
    new MyObject() { n = 3, t = "y" },
    new MyObject() { n = 4, t = "x" }
};

使用以下方式拆分类型:

var typeXs = allObjects.FindAll(i => i.t == "x");
var notTypeXs = allObjects.FindAll(i => i.t != "x");

var typeXs = allObjects.Where(i => i.t == "x").ToList<MyObject>();
var notTypeXs = allObjects.Except(typeXs).ToList<MyObject>();

或者你可以使用List.ForEach方法,它只迭代一次,因此理论上 应该优于其他两个选项。此外,它不需要引用LINQ库,这意味着它是.NET 2.0安全的。

var typeXs = new List<MyObject>();
var notTypeXs = new List<MyObject>();
allObjects.ForEach(i => (i.t == "x" ? typeXs : notTypeXs).Add(i));

答案 1 :(得分:1)

您可以将第二部分重写为

var notTypeXs = collectionOfThings.Except(typeXs);

答案 2 :(得分:0)

coll.GroupBy(o => o.Type == "TypeX");

答案 3 :(得分:0)

我不想在你身边进行共同体制,但我认为你应该考虑只迭代一次。

    // You can optimize this by specifying reasonable initial capacities.
List<TypedO> typeXs = new List<TypedO>();
List<TypedO> notTypeXs = new List<TypedO>();

foreach(TypedO o in list)
{
    (o.Type == "typeX" ? typeXs : notTypeXs).Add(o); // Yeah, I know.
}

(校正)

答案 4 :(得分:0)

如果您不希望两次通过列表,那么:

    var collectionOfThings = new[] 
        {
            new Thing { Id = 1, Type = "typeX" },
            new Thing { Id = 2, Type = "typeY" },
            new Thing { Id = 3, Type = "typeZ" },
            new Thing { Id = 4, Type = "typeX" }
        };


    var query = (from thing in collectionOfThings
                 group thing by thing.Type == "typeX" into grouped
                 //orderby grouped.Key descending
                 select new
                 {
                     IsTypeX = grouped.Key,
                     Items = grouped.ToList()
                 }).ToList();

    var typeXs = query.Find(x => x.IsTypeX).Items;
    var notTypeXs = query.Find(x => !x.IsTypeX).Items;

答案 5 :(得分:0)

我会使用'OfType'链接表达式,沿着以下几行:

var typeXs = collectionOfThigs.OfType<typeX>();
var notTypeXs = collectionOfThings.Except(typeXs);

(包括。除另一个答案外)。这确实假设你有类型,而不仅仅是类型字符串。

此外,如果不做出一次决定,可能会有性能损失(如果重要的话,分裂添加的if可能是要走的路),但除非性能有问题,否则清晰度是我的首选。