合并,联合,相交C#对象列表

时间:2018-10-03 23:27:18

标签: c# list linq c#-4.0 ienumerable

我正在尝试解决此问题:

我有多个字符串数组,其中一些包含重复项。我需要拿出一个最终列表,每个列表中包含最多的项目

a1 = Array{"A", "B", "C","D","E","F"}; 
a2 = Array{"A", "B", "B", "C","D","D","D","E","F"}; 
a3 = Array{"A", "B", "B", "C","D","D","E","F"};
a4 =  Array{"A", "B", "B", "B", "C","D","D","E","F"}; 
a5 = Array{"A", "B", "B", ","D","D","E","E","F"};

最终结果应该是:

FinalArray = {"A", "B", "B", "B", "C","D","D","D","E","E""F"};

最大发生在最终结果中的每个项目。

我该如何实现?

3 个答案:

答案 0 :(得分:0)

听起来像是一个作业问题,所以我不确定您是否应该使用特定的方法/逻辑来解决它,但我将描述如何解决。

解决问题。要求(据我所知)是显示每个值在任何一组中出现的最大次数。第一步是计算每个值在每个集合中出现的次数,可以先使用“ GroupBy”然后再进行“计数”汇总:

aN.GroupBy( v => v )
    .Select( g => new
    {
        Value = g.Key,
        Count = g.Count(),
    } );

类似地,我们然后将结果组合成一个单一的集合,并按值将其分组,以获得用于生成结果集的“最大”计数值:

combinedResults.GroupBy( at => at.Value )
    .Select( g => new
    {
        Value = g.Key,
        Count = g.Max( at => at.Count ),
    } );

在继续之前,让我们合并前两个步骤,但即使在此之前,我们也要将数组合并到自己的一组集合中。

var sets = new List<IEnumerable<string>>    
{
    new string[]{ "A", "B", "C", "D", "E", "F" },
    new string[]{ "A", "B", "B", "C", "D", "D", "D", "E", "F" },
    ... etc ...
};

var valueMaxCounts = sets
    .Select( s =>
        s.GroupBy( v => v )
            .Select( g => new
            {
                Value = g.Key,
                Count = g.Count(),
            } ) )
    .GroupBy( at => at.Value )
    .Select( g => new
    {
        Value = g.Key,
        Count = g.Max( at => at.Count ),
    } );

因此,现在我们有了一组值,每个值出现在输入集中之一的最大次数。现在,我们要遍历结果,并将每个值添加Count次。

var resultList = new List<string>();

foreach( var vmc in valueMaxCounts )
{
    //for( var i = 0; i < vmc.Count; ++I )
    //{
    //    resultList.Add( vmc.Value );
    //}

    resultList.AddRange( Enumerable.Repeat( vmc.Value, vmc.Count ) );
}

查询和循环的最后Select可以替换为对SelectMany的调用:

...query up to .GroupBy( at => at.Value )...
.SelectMany( g => Enumerable.Repeat( g.Key, g.Max( at => at.Count ) ) )

答案 1 :(得分:0)

解决此问题的一种简单方法是,首先创建一个列表来存储结果,然后遍历每个数组中的唯一项,然后将当前数组中的项数与项数之间的差值相加结果中(如果是正数)。

例如:

var arrays = new[]
{
    new[] {"A", "B", "C", "D", "E", "F"},
    new[] {"A", "B", "B", "C", "D", "D", "D", "E", "F"},
    new[] {"A", "B", "B", "C", "D", "D", "E", "F"},
    new[] {"A", "B", "B", "B", "C", "D", "D", "E", "F"},
    new[] {"A", "B", "B", "C", "D", "E", "E", "F"},
};

var result = new List<string>();

foreach (var array in arrays)
{
    var distinctItems = array.Distinct();

    foreach (var distinctItem in distinctItems)
    {
        var diff = array.Count(i => i == distinctItem) - 
                   result.Count(i => i == distinctItem);

        if (diff > 0) result.AddRange(Enumerable.Repeat(distinctItem, diff));
    }
}

Console.WriteLine(string.Join(", ", result.OrderBy(i => i)));

输出

enter image description here

答案 2 :(得分:0)

简单。

var arrays = new[]
{
    new[] {"A", "B", "C", "D", "E", "F"},
    new[] {"A", "B", "B", "C", "D", "D", "D", "E", "F"},
    new[] {"A", "B", "B", "C", "D", "D", "E", "F"},
    new[] {"A", "B", "B", "B", "C", "D", "D", "E", "F"},
    new[] {"A", "B", "B", "C", "D", "E", "E", "F"},
};

var result =
    arrays
        .SelectMany(xs => xs.GroupBy(x => x).Select(x => new { x.Key, Count = x.Count() }))
        .GroupBy(x => x.Key, x => x.Count)
        .Select(x => new { x.Key, Count = x.Max() })
        .SelectMany(x => Enumerable.Repeat(x.Key, x.Count))
        .ToArray();

给出:A, B, B, B, C, D, D, D, E, E, F