我有一个包含以下项目的简单数组:
[4, 3, 1, 1, 0, 0]
我想以这种方式对它进行排序:
[4, 3, 1, 0, 1, 0]
正如您所注意到的,我想按降序对其进行排序。但在这种情况下,有两组数组按降序排序:
4, 3, 1, 0 and 1, 0
产生输出:
[4, 3, 1, 0, 1, 0]
我尝试使用Group By:
执行此操作var result = arrayInput.GroupBy(c => c).Select(a => a.OrderBy(d => d).First());
但是这只生成4, 3, 1, 0
,我需要将未选择的整数附加为已排序,以便它将是:
[4, 3, 1, 0, 1, 0]
答案 0 :(得分:1)
这是我如何做到的。基本上你想尝试将每个数字放入一组集合中。第一个没有这个数字的是它实际进入的那个,如果没有它,那么你添加一个新的集合。通过这种方式,第一组将具有所有唯一数字,第二组具有至少一次重复的所有数字,依此类推。然后在最后,您将返回每个集合的项目,并按顺序排列每个集合。
public static IEnumerable<int> SetSort(this IEnumerable<int> nums) {
var sets = new List<HashSet<int>>();
foreach(var num in nums) {
bool added = false;
foreach(var set in sets) {
added = set.Add(num);
if(added) break;
}
if(!added){
sets.Add(new HashSet<int> { num });
}
}
foreach(var set in sets) {
foreach(var num in set.OrderByDescending(x => x)) {
yield return num;
}
}
}
答案 1 :(得分:1)
通常Aggregate
扩展方法可以做任何事情
var data = new[] { 1, 2, 3, 4, 1, 0, 1, 0 };
var result =
data.GroupBy(i => i)
.OrderByDescending(group => group.Key)
.Aggregate(new { Keys = new List<int>(), Duplicates = new List<int>() },
(lists, group) =>
{
lists.Keys.Add(group.Key);
var duplicates = Enumerable.Repeat(group.Key, group.Count() - 1);
lists.Duplicates.AddRange(duplicates);
return lists;
},
lists => lists.Keys.Concat(lists.Duplicates));
// result is new[] { 4, 3, 2, 1, 0, 1, 1, 0 };
使用不可变集合的方法
private IEnumerable<int> SortFunc(IEnumerable<int> data)
{
var ordered =
data.GroupBy(i => i)
.OrderByDescending(group => group.Key)
.Select(group => new
{
Key = group.Key,
Duplicates = group.Skip(1)
});
foreach (var key in ordered.Select(group => group.Key))
{
yield return key;
}
foreach (var value in ordered.SelectMany(group => group.Duplicates))
{
yield return value;
}
}