C# 使用LINQ从列表中返回选择对象和仅所需的子值
我找不到这个看似简单的LINQ问题的解决方案 我试图返回一个对象列表,其中每个对象在属性子列表中都有特定的值。我需要返回对象,并且只返回那些子列表值 例: 我的课程简化了:C# 使用LINQ从列表中返回选择对象和仅所需的子值,c#,linq,C#,Linq,我找不到这个看似简单的LINQ问题的解决方案 我试图返回一个对象列表,其中每个对象在属性子列表中都有特定的值。我需要返回对象,并且只返回那些子列表值 例: 我的课程简化了: public class Fruit() { public List<KeyValuePairs> items {get;set;) } 我的水果清单: fruitList = new List<Fruit>(){Fruit1, Fruit2, Fruit3, Fruit4} Fruit1
public class Fruit()
{
public List<KeyValuePairs> items {get;set;)
}
我的水果清单:
fruitList = new List<Fruit>(){Fruit1, Fruit2, Fruit3, Fruit4}
Fruit1.items = {name: apple, color: red}
Fruit2.items = {name: apple, color: green}
Fruit3.items = {name: apple, date: 2020}
Fruit4.items = {name: grape, color: green}
我感谢你的帮助 不保留对象实际实例的解决方案:
fruitList.Where(f => f.items.Any(i => i.Key == "color")).Select(f => new Fruit { items = f.items.Where(i => i.Key == "color").ToList() });
这是使用Linq Select STATION完成的,在该STATION中,您传递返回所需内容的lambda函数。这在您希望在返回对象之前在对象上传递特定实现时非常有用。大致如下:
fruitList.Where(x => x.Value == "red").Select(s =>
{
return s.Value;
});
编辑
使用Linq似乎是最好的主意
var result = from fruit in fruitList
where fruit.items.Any(i => i.Key == "color")
select new {Color = fruit.items.First(i => i.Key == "color").Value};
这将返回匿名类型。LINQ适用于筛选和查询,但不适用于修改数据。由于要更改原始对象以过滤成员项,因此需要在找到它们后对每个对象进行处理 首先,使用LINQ获取适当水果对象的列表: 修改每个水果,使其仅包含所需的项目成员: 显然,你物品中的钥匙是独一无二的。您没有两个键颜色为的KeyValuePairs 其他人给出的以下内容将起作用:
var result = from fruit in fruitList
where fruit.items.Any(i => i.Key == "color")
select new {Color = fruit.items.First(i => i.Key == "color").Value};
但是,为此,您将多次扫描项目序列:一次以查看是否至少有一个具有值颜色的键,丢弃结果,然后从第一个项目重新开始以查找具有键颜色的第一个项目
当然,这可以做得更有效:从每个水果中,获取其数据和第一个项,其键等于颜色或默认值,然后扔掉所有没有第一个项的水果
在您可能简化的示例中,水果只有一个项目。在这种情况下,可以做得更简单。但我们先假设一个水果还有我想要的几个其他属性:
string keyToSelect = "color";
var result = fruits.Select(fruit => new
{
SelectedItem = fruit.Items
.Where(item => item.Key == keyToSelect)
.FirstOrDefault(),
// Select other Fruit properties that you plan to use,
// or skip this if a Fruit has no other properties
Name = fruit.Name,
...
})
// Keep only those Fruits that have a FirstItemWithKeyToSelect:
.Where(fruit => fruit.SelectedItem!= null);
这将获取第一个水果,并开始枚举这些项目,直到找到第一个Key==color的项目。它记住这个项目,ans跳过其余的项目。然后它继续第二个水果的项目,等等,直到它列举了所有水果
所以物品最多只能扫描一次。找到某个水果的合适项目后,不会扫描该水果的其余项目。水果没有名为Value的属性。它封装了一个键/值列表,类似这样的方法可能会有所帮助:。Selects=>{return s.items.Whereitm=>itm.Value.StartsWithy.Selectitm=>{return itm.Value;}.ToList;};您可以忽略ToList或将其转换为不同的类型您需要显示实际的C类型而不是模糊的伪类型才能得到答案。返回原始对象并修改原始对象项成员以使其具有不同的数据似乎不是一个好主意,但如果这是您真正想要的,那么LINQ单独用于查询,而不是修改对象。我假设您的类KeyValuePair是一个打字错误,您指的是KeyValuePairs.Fruit1.items={name:apple,color:red}毫无意义;这不是合法的c语法。请使用实际示例更新代码。你是说水果1.items=newlist{newkeyvaluepair{Key=apple,Value=red}}?但如果是这样,颜色在哪里起作用呢?这个问题目前无法回答。当然我会正确回答,但你能先帮我解决代码中的这些红色曲线吗?谢谢Harald,我想我的一个问题是我没有意识到你可以从LINQ查询中生成新对象,或者,通过创建新对象,与仅过滤原始对象列表相比,查询效率会受到影响。我的印象是,我可以从每个object items属性中删除数据并返回原始对象。你发布的内容更加清晰,并且完成了工作。干杯
var result = from fruit in fruitList
where fruit.items.Any(i => i.Key == "color")
select new {Color = fruit.items.First(i => i.Key == "color").Value};
var ans = fruitList.Where(f => f.items.Any(kv => kv.Key == "color")).ToList();
foreach (var fruit in ans)
fruit.items = fruit.items.Where(kv => kv.Key == "color").ToList();
// ans is original Fruit objects now with filtered items members
var result = from fruit in fruitList
where fruit.items.Any(i => i.Key == "color")
select new {Color = fruit.items.First(i => i.Key == "color").Value};
string keyToSelect = "color";
var result = fruits.Select(fruit => new
{
SelectedItem = fruit.Items
.Where(item => item.Key == keyToSelect)
.FirstOrDefault(),
// Select other Fruit properties that you plan to use,
// or skip this if a Fruit has no other properties
Name = fruit.Name,
...
})
// Keep only those Fruits that have a FirstItemWithKeyToSelect:
.Where(fruit => fruit.SelectedItem!= null);