我正在尝试解决此问题:
我有多个字符串数组,其中一些包含重复项。我需要拿出一个最终列表,每个列表中包含最多的项目
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"};
最大发生在最终结果中的每个项目。
我该如何实现?
答案 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)));
输出
答案 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