从嵌套列表中获取项目

时间:2017-10-26 11:54:01

标签: c# linq

我有一个包含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 }));
    }
}

以下是两个清单的规则:

列表A只包含唯一的数字 - 它们永远不会在自己的HashSet或任何其他ListA HashSet中重复。

列表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,但似乎无法得到我需要的结果。

3 个答案:

答案 0 :(得分:2)

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,如果是,则将其ListA元素添加到结果中。

如果仅比较Hashsets而不依赖于其他Hashsets,则可以使用Intersect / Union / Except等。(设置理论的东西)。

答案 1 :(得分:1)

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);

答案 2 :(得分:0)

我认为你想要返回2套

的交集

有一个Linq函数可以执行此操作

var commonInBoth = List1.Intersect(List2);