如何解决使用LINQ从列表列表中返回选择对象和仅所需的子值
对于这个看似简单的LINQ问题,我找不到解决方案。
我正在尝试返回对象列表,其中每个对象在属性子列表中都具有特定值。我需要返回对象,仅返回那些子列表值
例如:
我的课程简化了:
public class Fruit()
{
public List<KeyValuePairs> items {get;set;)
}
public class KeyValuePair()
{
public string Key {get;set;}
public string Value {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}
仅返回子列表中带有“颜色”的水果,并且仅返回其子列表中的“颜色”键/值。因此结果看起来像:
Fruit1.items = {color: red}
Fruit2.items = {color: green}
Fruit4.items = {color: green}
感谢您的帮助!
解决方法
使用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};
这将返回匿名类型。
,显然,您的#ifndef HASHING_H
#define HASHING_H
/* If we are we on Windows,we want a single define for it.*/
#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__))
#define _WIN32
#endif /* _WIN32 */
#if defined(_WIN32) && defined(_HASHING_BUILD_DLL)
/* We are building Hashing as a Win32 DLL */
#define HASHING_API __declspec(dllexport)
#elif defined(_WIN32) && defined(HASHING_DLL)
/* We are calling Hashing as a Win32 DLL */
#define HASHING_API __declspec(dllimport)
#elif defined(__GNUC__) && defined(_HASHING_BUILD_DLL)
/* We are building Hashing as a shared / dynamic library */
#define HASHING_API __attribute__((visibility("default")))
#else
/* We are building or calling HASHING as a static library */
#define HASHING_API
#endif
//your inlcudes
class HASHING_API MyClass
{
//...
};
#endif // !HASHING_H
中的Key
是唯一的。您没有两个带有Items
“颜色”的KeyValuePairs
。
其他人给出的以下内容将起作用:
Key
但是,为此,您将多次扫描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};
的序列:一次以查看是否至少有一个Items
的值为“ color”,丢弃结果,然后重新开始在第一个Key
处,找到第一个Item
为“颜色”的Item
。
当然可以提高效率:从每个Key
中获取其数据及其第一个Fruit
,且其中Item
等于“颜色”或默认值,然后丢弃每个{ {1}}中没有这样的第一个Key
。
在您的(可能是简化的)示例中,水果只有项目。在这种情况下,它甚至可以更简单地完成。但首先让我们假设一个水果具有我想要的其他一些属性:
Fruit
这将获取您的第一个Fruit,并开始枚举Items,直到找到Key ==“ color”的第一个Fruit。它会记住该项目,ans会跳过其余项目。然后继续第二个水果的项目,依此类推,直到列举了所有水果为止。
因此,物品最多只能扫描一次。找到某个水果的合适项目后,将不扫描该水果的其余项目。
,不保留对象实际实例的解决方案:
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方法完成的,您在其中传递了lambda函数,该函数返回所需的内容。这在您想在返回对象之前传递对象的特定实现时非常有用。类似于以下内容:
fruitList.Where(x => x.Value == "red").Select(s =>
{
return s.Value;
});
修改
.Select(s =>
{
return s.items.Where(itm=>itm.Value.StartsWith("y"))
.Select(itm => { return itm.Value; }).ToList<string>();
});
,
LINQ适合过滤和查询,但不适用于修改数据。由于您想更改原始对象以过滤items
成员,因此需要在找到它们之后对其进行处理。
-
首先,使用LINQ获取适当的
Fruit
对象的列表:var ans = fruitList.Where(f => f.items.Any(kv => kv.Key == "color")).ToList();
-
将每个
Fruit
修改为仅具有所需的items
成员: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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。