按类别区分,然后在一列中加入每个类别的所有不同值

时间:2018-05-08 06:07:54

标签: c# linq

我有这个数据:

CategoryId  Value     
1            val1   
1            val2  
1            val2
2            test1  
2            test1  
3            data1  
3            data2 
3            data2

我想要的输出是这样的:

CategoryId        Value
1                  val1. val2.
2                  test1.
3                  data1. data2.

输出应该在CategoryId中是唯一的,并且每个类别只应显示不同的值并以1列值连接在一起。 (假设值是长度为1到3个句子的字符串值)。 我如何在LINQ中查询?或者我如何将它与我想要的输出分组?

3 个答案:

答案 0 :(得分:5)

Join CategoryId和Distinct var distinctCategory = categoryList.GroupBy(x => x.CategoryId) .Select(x => new Category() { CategoryId = x.Key, Value = string.Join(". ", x.Select(y => y.Value).Distinct()) });

let initialState = {
  items: [],
  itemsCount: 0,
  completedCount: 0
};

https://dotnetfiddle.net/0Z04AY

答案 1 :(得分:0)

听起来您希望按类别ID对值进行分组,然后在组中使用不同的值。

这可以通过一次GroupBy调用完成:

var query = input.GroupBy(
    item => item.CategoryId,              // Key projection
    item => item.Value,                   // Element projection
    // Result projection. (You may want to add ToList within the lambda to materialize.)
    (key, values) => new { Key = key, Values = values.Distinct() });

这是一个包含示例数据的完整程序:

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var input = new[]
        {
            new { CategoryId = 1, Value = "val1" },
            new { CategoryId = 1, Value = "val2" },
            new { CategoryId = 1, Value = "val2" },
            new { CategoryId = 2, Value = "test1" },
            new { CategoryId = 2, Value = "test1" },
            new { CategoryId = 3, Value = "data1" },
            new { CategoryId = 3, Value = "data2" },
            new { CategoryId = 3, Value = "data2" },
        };

        var query = input.GroupBy(
            item => item.CategoryId,              // Key
            item => item.Value,                   // Element
            // Projection of results
            (key, values) => new { Key = key, Values = values.Distinct() });

        foreach (var element in query)
        {
            Console.WriteLine($"{element.Key}: {string.Join(", ", element.Values)}");
        }
    }
}

或者,您可以按类别ID对值进行分组,然后在使用时执行Distinct()部分:

var query = from item in input
            group item.Value by item.CategoryId;

foreach (var group in query)
{
    var values = group.Distinct();
    Console.WriteLine($"{group.Key}: {string.Join(", ", values)}");
}
当然,可以在查询中使用string.Join - 但我通常会等到最后一刻将逻辑数据转换为显示表示。如果你想用第一个例子做到这一点,你只需使用:

var query = input.GroupBy(
    item => item.CategoryId,              // Key projection
    item => item.Value,                   // Element projection
    // Result projection. (You may want to add ToList within the lambda to materialize.)
    (key, values) => new { Key = key, Values = string.Join(", ", values.Distinct()) });

请注意,我已使用逗号而非句点加入值。无论如何,您的原始预期输出无法实现string.Join和一段时间,因为您也有一个尾随期。您可以通过投影然后进行string.Concat调用来获得确切的输出,例如

foreach (var element in query)
{
    var periodValues = element.Values.Select(x => x + ". ");
    Console.WriteLine($"{element.Key}: {string.Concat(periodValues)}");
}

答案 2 :(得分:0)

这是经过测试和运作的解决方案。

List<Data> data = new List<Data>();
data.Add(new Data(){CategoryId = 1,Value = "val1"});
data.Add(new Data(){CategoryId = 1,Value = "val2"});
data.Add(new Data(){CategoryId = 1,Value = "val2"});
data.Add(new Data(){CategoryId = 2,Value = "test1"});
data.Add(new Data(){CategoryId = 2,Value = "test1"});
data.Add(new Data(){CategoryId = 3,Value = "data1"});
data.Add(new Data(){CategoryId = 3,Value = "data2"});
data.Add(new Data(){CategoryId = 3,Value = "data2"});

var result = data.Distinct()
.GroupBy(d => d.CategoryId, d=>d.Value, (k,v) => new { Key=k, Values = v.Distinct()  } )
.Select(d => new Data()
{
    CategoryId = d.Key,
    Value = string.Join(". ", d.Values.ToList())
}).ToList();