【问题标题】:Linq - Grouping where items fall in multiple groups?Linq - 将项目分为多个组的分组?
【发布时间】:2023-03-26 17:41:01
【问题描述】:

是否可以使用 Linq 创建一个组,其中项目属于多个组?

使用以下简单示例:

    public class Data
    {
        public string ID;
        public int From;
        public int To;
    }

还有这份清单:

    List<Data> data = new List<Data>() 
    {
        new Data() { ID = "A", From = 1, To = 3 }, // Call this A
        new Data() { ID = "B", From = 1, To = 2 }, // Call this B
        new Data() { ID = "C", From = 2, To = 3 }  // Call this C
    };

我想按 From 和 To 范围内的每个可能的整数进行分组(尽管我可以为查询提供我想要的范围,例如 1 到 3,而不是找到 min + max),并且在每个组中将是对分组 int 适合其范围的 Data 实例的引用。

很难解释,更容易展示每个组和我期望在每个组中出现的实例:

[Group 1] 1 - A, B
[Group 2] 2 - A, B, C
[Group 3] 3 - A, C

这可能吗?或者组必须是互斥的?

编辑:加入方式可以做到这一点吗?

int[] range = new int[] { 1, 2, 3 };

var query = from d in data
    from r in range
    where d.From <= r && d.To >= r
    group d by r into g
    select g;

如果不首先确定范围,这可能吗?

编辑#2:使用答案二和重构,您可以:

 var result = Enumerable.Range(1,3)
                        .Select(i => new
                                     {
                                       Key = i,
                                       Values = data.Where(d => i >= d.From &&
                                                           i <= d.To)
                                      });

这还有一个额外的好处,即在没有任何适合的 Data 实例的情况下也返回范围内的数字,这正是我所需要的。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    试试Join,而不是GroupBy。我相信分组是相互排斥的。将您想要的“分组”值加入到From &lt;= Value AND To &gt;= Value上的数据列表中

    编辑 (回答您的评论) 你可以像这样得到你的范围:

    int min = data.Min(a => a.From);
    int max = data.Max(a => a.To);
    List<int> range = new List<int>();
    for (int i = min; i <= max; i++)
        range.Add(i);
    

    【讨论】:

    • 我认为您可能是对的,我已经编辑了我的问题以显示我尝试过的具有预期效果的东西。如果我不必先创建一个范围会很好吗?
    【解决方案2】:

    GroupBy 对项目进行分组,使得没有项目在一个以上的组中。

    这应该做你想做的:

    var result = data.SelectMany(d => Enumerable.Range(d.From, d.To - d.From + 1))
                     .Distinct()
                     .Select(i => new
                                  {
                                      Key = i,
                                      Values = data.Where(d => i >= d.From &&
                                                               i <= d.To)
                                  });
    

    不过,我不知道这是否比您已有的解决方案有很大改进。

    【讨论】:

    • 干杯,这实际上非常有用,我已经稍微重构了它并将其添加到我的问题中。我试图得到这样的情况,即使它们没有任何数据条目,我也会返回范围内的数字,这让我到了那里。
    猜你喜欢
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 2015-01-06
    相关资源
    最近更新 更多