C# 基于属性值将对象放入单独列表的最灵活方法
我有一个对象集合,我很好奇如何将它们分成两个列表——一个列表包含特定类型的所有内容,另一个列表包含其余内容。我想到的一种方法是:C# 基于属性值将对象放入单独列表的最灵活方法,c#,.net,linq,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); 另一种方法是循环收集内容,并根据if/else进行
var typeXs = (from o in collectionOfThings where o.Type == "typeX" select o);
var notTypeXs = (from o in collectionOfThings where o.Type != "typeX" select o);
另一种方法是循环收集内容,并根据if/else进行分配
这两种方法都简单易读,但我只是想知道是否有更巧妙的方法?您可以将第二部分改写为
coll.GroupBy(o => o.Type == "TypeX");
var notTypeXs = collectionOfThings.Except(typeXs);
你可以把第二部分改写成
var notTypeXs = collectionOfThings.Except(typeXs);
< >我不想对你进行优化,但我认为你应该只考虑一次迭代。< /P>
// 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.
}
//您可以通过指定合理的初始容量对其进行优化。
列表类型xs=新列表();
List notTypeXs=新列表();
foreach(列表中的TypedO o)
{
(o.Type==“typeX”?typeXs:notTypeXs)。添加(o);//是的,我知道。
}
(修正)
< P>我不想对你进行优化,但我认为你应该只考虑一次迭代。 // 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.
}
//您可以通过指定合理的初始容量对其进行优化。
列表类型xs=新列表();
List notTypeXs=新列表();
foreach(列表中的TypedO o)
{
(o.Type==“typeX”?typeXs:notTypeXs)。添加(o);//是的,我知道。
}
(已更正)此示例应说明您的目标:
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.Where(i=>i.t==“x”).ToList();
var notTypeXs=allObjects.Except(typeXs.ToList();
或者,您可以使用List.ForEach方法,该方法只迭代一次,因此理论上应优于其他两个选项。此外,它不需要引用LINQ库,这意味着它是.NET2.0安全的
var typeXs = new List<MyObject>();
var notTypeXs = new List<MyObject>();
allObjects.ForEach(i => (i.t == "x" ? typeXs : notTypeXs).Add(i));
var typeXs=newlist();
var notTypeXs=新列表();
ForEach(i=>(i.t==“x”?typeXs:notTypeXs.Add(i));
此示例应说明您的目标:
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.Where(i=>i.t==“x”).ToList();
var notTypeXs=allObjects.Except(typeXs.ToList();
或者,您可以使用List.ForEach方法,该方法只迭代一次,因此理论上应优于其他两个选项。此外,它不需要引用LINQ库,这意味着它是.NET2.0安全的
var typeXs = new List<MyObject>();
var notTypeXs = new List<MyObject>();
allObjects.ForEach(i => (i.t == "x" ? typeXs : notTypeXs).Add(i));
var typeXs=newlist();
var notTypeXs=新列表();
ForEach(i=>(i.t==“x”?typeXs:notTypeXs.Add(i));
如果您不想浏览列表两次,那么:
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;
如果您不想浏览列表两次,那么:
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;
我将使用“OfType”链接表达式,大致如下:
var typeXs = collectionOfThigs.OfType<typeX>();
var notTypeXs = collectionOfThings.Except(typeXs);
var typeXs=collectionOfThigs.OfType();
var notTypeXs=除(typeXs)之外的所有内容的集合;
(包括其他答案除外)。但是,这确实假设您拥有类型,而不仅仅是类型字符串
此外,如果不做一次决定,可能会对性能造成影响(如果重要的话,使用拆分添加的if可能是一种方法),但除非性能有问题,否则我更喜欢清晰性。我会使用“OfType”链接表达式,大致如下:
var typeXs = collectionOfThigs.OfType<typeX>();
var notTypeXs = collectionOfThings.Except(typeXs);
var typeXs=collectionOfThigs.OfType();
var notTypeXs=除(typeXs)之外的所有内容的集合;
(包括其他答案除外)。但是,这确实假设您拥有类型,而不仅仅是类型字符串
此外,如果不做一次决定,可能会受到性能惩罚(如果重要的话,使用拆分加法的if可能是一种方法),但除非性能有问题,否则清晰性是我的首选。我不确定如何处理返回的IEnumerable我不确定如何处理返回的IEnumerable Hanks,我曾经想过:“另一种方法是循环收集东西,然后根据if/else分配。”如果我是多余的,我很抱歉。我只是不得不推荐这个选项,严格地说,我没有使用if或else.:)谢谢,我已经想到了:“另一种方法是循环收集内容,然后根据if/else进行分配。”如果我是多余的,很抱歉。我只是不得不推荐这个选项,严格地说,我没有使用if或else.:)我认为这是最干净、最有表现力的方式。我认为这是最干净、最有表现力的方式。第二个例子可能是最好的,但很好地给出了所有选项+1而且它只对集合进行一次迭代,其他两个选项实际上都必须对集合进行两次迭代,尽管它们可能编写得更优雅一些。第二个示例可能是最好的,但很好地给出了所有选项+1而且它只对集合进行一次迭代,其他两个选项实际上都必须对集合进行两次迭代,尽管它们可能编写得更优雅一些。