Сортировать массив двойников и возвращать отсортированный массив исходных индексов

Я хочу отсортировать массив двойников, но я хочу сохранить исходные индексы. Я пробовал следующее -

double[] circs = new double[noOfCircs];

Инициализировать циклы со значениями...

int[] loc = Enumerable.Range(0, noOfCircs-1).ToArray();
Array.Sort(circs, loc);

После сортировки я хочу использовать массив loc для дальнейших вычислений. Что я делаю не так?


person arzee    schedule 26.11.2018    source источник
comment
Сортировка массива — это изменение позиции значения в массиве, а значит, изменится и индекс. Чтобы сохранить предыдущие позиции, вам понадобится другая коллекция для хранения значения и исходного индекса.   -  person Renatas M.    schedule 26.11.2018
comment
Я использую другой массив для хранения индекса. Массив loc в приведенном выше коде используется для хранения значений индекса.   -  person arzee    schedule 26.11.2018
comment
Просто для моего понимания. У вас есть double[] со значениями, которые вы хотите отсортировать. Но вы не хотите изменять этот исходный массив, поэтому вы пытаетесь сохранить индексы исходного массива в отсортированном виде в int[] ? Вы пытались создать отсортированную копию исходного массива double[], перебрать новый, найти значения в старом массиве и сохранить их индекс в массиве loc?   -  person Vulpex    schedule 26.11.2018
comment
var result = circs.Select((s,i) => new { Value = s, Index = i }).OrderBy(o => o.Value); это вернет упорядоченную коллекцию (IOrderedEnumerable) анонимного объекта, которую вы можете использовать по своему усмотрению. Это то, что вы хотите?   -  person SᴇM    schedule 26.11.2018
comment
@Vulpex Вы правы для целей этого обсуждения. :) У меня ~10000 значений в двойном массиве. Я думал, что использование метода Sort будет быстрее, чем повторение множества из них. Я ошибаюсь? Кроме того, как я уже сказал, у меня есть дополнительные операции, которые нужно выполнить после того, как у меня будут отсортированные индексы.   -  person arzee    schedule 26.11.2018
comment
@SeM - я не уверен, что полностью понимаю твое объяснение. Не могли бы вы уточнить?   -  person arzee    schedule 26.11.2018
comment
@arzee Если вы можете использовать Linq, и я не уверен на 100% в производительности (вы можете проверить это самостоятельно), первая часть circs.Select((s,i) => new { Value = s, Index = i }) создаст коллекцию IEnumerable<'a> (где 'a — анонимный тип, содержащий Value и Index), вторая часть сортировка этой новой коллекции по Value. В конце у вас будет IOrderedEnumerable<'a> result, который будет содержать упорядоченный массив и индексы ранее.   -  person SᴇM    schedule 26.11.2018
comment
Чего вы пытаетесь достичь? Sort method would be faster than iterating through the lot of them Что ты хотел этим сказать? Пожалуйста, отредактируйте свой вопрос, добавьте подробности, что вы пытаетесь сделать, что вы сделали, что было не так и каков был ожидаемый результат.   -  person Renatas M.    schedule 26.11.2018
comment
@arzee, возможно, вам нужна эта скрипка? Не самый эффективный, но работает.   -  person Vulpex    schedule 26.11.2018
comment
Что не работает? Я могу сказать, что второй аргумент Range неверен, но в чем проблема, которую вы определили?   -  person usr    schedule 26.11.2018


Ответы (2)


Я предлагаю Linq с помощью анонимных классов:

using System.Linq;

...

double[] circs = ...

int[] loc = circs
  .Select((value, index) => new { // for each item we store
     value = value,               //   its value
     index = index                //   and original index
   })
  .OrderBy(pair => pair.value)  // Order by values
  .Select(pair => pair.index)   // By return original index
  .ToArray();
person Dmitry Bychenko    schedule 26.11.2018
comment
Было бы интересно сравнить производительность этого решения с анонимными типами и кортежами значений C# 7. Кортежи значений копировали бы больше памяти, но имели бы лучшую локальность (и создавали бы меньше давления при сборе), поэтому трудно сказать, какой из них будет более производительным, не попробовав его. - person Eric Lippert; 26.11.2018

Вы можете преобразовать двойной массив в список, а затем вместо этого отсортировать список. Таким образом, у вас все еще будет исходный двойной массив.

 List<double> list = doubleArray.ToList();
 list.Sort();
person Amey Vartak    schedule 26.11.2018