从嵌套列表中获取项目

Posted

技术标签:

【中文标题】从嵌套列表中获取项目【英文标题】:Get items from nested list 【发布时间】:2017-10-26 11:54:00 【问题描述】:

我有一个包含 2 个其他列表的类的列表(实际上是 HashSet)。这是带有示例数据的模型:

public class Example

    public Example(HashSet<int> a, HashSet<int> b)
    
        ListA = a;
        ListB = b;
    

    public HashSet<int> ListA  get; set; 
    public HashSet<int> ListB  get; set; 


public class UseCase

    public UseCase()
    
        var hs = new HashSet<Example>();
        hs.Add(new Example(new HashSet<int>  1, new HashSet<int>  100, 200 ));
        hs.Add(new Example(new HashSet<int>  2,3,4,5 , new HashSet<int>  100, 200, 300 ));
        hs.Add(new Example(new HashSet<int>  6,9,12 , new HashSet<int>  200, 300 ));
    

以下是两个列表的规则:

List A 只包含唯一的数字——它们从不重复,无论是在它们自己的 HashSet 中还是在任何其他 ListA HashSet 中。

List B 包含在其自己的 HashSet 中唯一的数字,但它们可能在一个或多个 List B HashSet 中重复。

我要做的是返回匹配 ListA 行中的所有数字,其中 ListB 中存在特定数字。

这是一个模拟 linq 查询:

public static IEnumerable<int> GetDistinctFromListA(int b)

    return UsesCases
        .Where(x => x.ListB.Contains(b))

所以,此时我有许多行,但我现在需要从匹配的 ListB 列表中提取所有数字。如果输入的参数是 100,那么我希望返回一个包含数字 1、2、3、4 和 5 的列表。

我一直在玩 All 和 SelectMany,但似乎无法得到我需要的结果。

【问题讨论】:

什么是用例? hs.Where(x =&gt; x.ListB.Contains(100)).SelectMany(x =&gt; x.ListA) 适合我吗? --> SelectManyIterator 1, 2, 3, 4, 5 @Patrick - 它只代表我创建的集合 - 它是一个静态 HashSet,与 UseCase 类中的相同 您真的不应该将哈希集称为“列表”。它们不是列表,它们是哈希集。 【参考方案1】:
public class Example

    public Example(HashSet<int> a, HashSet<int> b)
    
        ListA = a;
        ListB = b;
    

    public HashSet<int> ListA  get; set; 
    public HashSet<int> ListB  get; set; 


static IEnumerable<int> GetDistinctFromListA(HashSet<Example> hs, int b)

    var rv = hs.Aggregate(new HashSet<int>(), (acc, el) =>
    
        if (el.ListB.Contains(b)) acc.UnionWith(el.ListA);
        return acc;
    );

    return rv;


static void Main(string[] args)

    var hs = new HashSet<Example>();
    hs.Add(new Example(new HashSet<int>  1 , new HashSet<int>  100, 200 ));
    hs.Add(new Example(new HashSet<int>  2, 3, 4, 5 , new HashSet<int>  100, 200, 300 ));
    hs.Add(new Example(new HashSet<int>  6, 9, 12 , new HashSet<int>  200, 300 ));

    foreach (var b in hs.SelectMany(e => e.ListB).Distinct())
        Console.WriteLine($"b => string.Join(",", GetDistinctFromListA(hs, b))");

    Console.ReadLine();

这会遍历 hs 的所有元素,检查每个元素 ListB 是否包含 b,如果包含 b,则将其 ListA 元素添加到结果中。

如果你只比较哈希集而不依赖于其他哈希集,你可以使用相交/联合/除外等(集合理论的东西)。

【讨论】:

我认为这是正确的做法。另外,我认为您错过了结束); 还有一件事。显然HashSet 没有AddRange,但它确实有UnionWith 会给出正确的结果【参考方案2】:

HashSet 意味着只包含唯一值,也就是说,您所做的所有查询都会返回不同的值。如果要查找两个HashSet 之间的交集,可以调用Intersect 方法。

例如:

//The additional 1 is ignored here
HashSet<int> A = new HashSet<int>  1, 1, 2, 3, 4, 5 ;
HashSet<int> B = new HashSet<int>  1, 5, 8, 9 ;
var Result = A.Intersect(B);

【讨论】:

【参考方案3】:

我想你想返回 2 个集合的交集

有一个 Linq 函数可以做到这一点

var commonInBoth = List1.Intersect(List2);

【讨论】:

以上是关于从嵌套列表中获取项目的主要内容,如果未能解决你的问题,请参考以下文章

从嵌套字典中动态删除项目

即使项目不连续使用Python,如何从长嵌套列表中删除短列表?

从多个嵌套的列表中更新一个项目

将mysql查询中项目的嵌套列表属性映射到c#对象

从嵌套 recyclerview 的所有输入框中获取所有编辑文本正在获取最新的 recyclerview 项目而不是所有数据

如何使用LINQ从列表中获取重复项?