【问题标题】: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 类中的相同
  • 您真的不应该将哈希集称为“列表”。它们不是列表,它们是哈希集。

标签: c# linq


【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2015-10-15
      • 2022-10-12
      • 2019-03-22
      相关资源
      最近更新 更多