Сортировать список int не последовательно - PullRequest
0 голосов
/ 08 мая 2019

Учитывая List<int> как { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4 }, я бы хотел получить { 1, 2, 3, 4, 1, 2, 3, 1, 2, 3 }.У меня есть рабочий код, но я хотел бы найти более элегантный / аккуратный способ решения этой проблемы.

var list = new List<int>() { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4 };
var sortedList = new List<int>();
var set = new HashSet<int>();

while (list.Count > 0)
{
    foreach (var l in list)
    {
        set.Add(l);
    }
    sortedList.AddRange(set);

    foreach(var s in set)
    {
        list.Remove(s);
    }
    set.Clear();
}

// sortedList -> {1, 2, 3, 4, 1, 2, 3, 1, 2, 3}

1 Ответ

4 голосов
/ 08 мая 2019

Можно попробовать Linq ; сначала мы превращаем начальные list в группы

  {1, 1, 1}
  {2, 2, 2}
  {3, 3, 3}
  {4}

Затем перечислите элементы в этих группах - {{1, 2, 3, 4}, {1, 2, 3}, {1, 2, 3}} и сгладьте их: {1, 2, 3, 4, 1, 2, 3, 1, 2, 3}. Давайте извлечем его как метод:

Код:

private static List<int> MySort(IEnumerable<int> list) {
  var groups = list
   .GroupBy(item => item)
   .Select(chunk => new {
     value = chunk.Key,
     count = chunk.Count()
   })
   .OrderBy(item => item.value)
   .ToArray();

  int maxCount = groups.Max(group => group.count);

  return Enumerable
    .Range(0, maxCount)
    .SelectMany(i => groups
       .Where(chunk => chunk.count > i)
       .Select(chunk => chunk.value))
    .ToList();
}

Демо-версия:

List<int>[] tests = new List<int>[] {
  new List<int>() { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4 },
  new List<int>() { 1, 1, 1, 3, 4, 4, 4, 4, 4, 5, 10 },
};

var demo = string.Join(Environment.NewLine, tests
  .Select(test => $"{string.Join(", ", test),-35} -> {string.Join(", ", MySort(test))}"));

Console.Write(demo);

Результат:

1, 1, 1, 2, 2, 2, 3, 3, 3, 4        -> 1, 2, 3, 4, 1, 2, 3, 1, 2, 3
1, 1, 1, 3, 4, 4, 4, 4, 4, 5, 10    -> 1, 3, 4, 5, 10, 1, 4, 1, 4, 4, 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...