2012-12-12 4 views
2

Я хочу взять List и сгенерировать Dictionary, который отображает каждый элемент в его индекс в List. Я могу это сделать, как это так, для List<string>:Создайте карту индексов элементов списка, используя Linq

var myList = new List<string>{ /* populate list */ }; 
var orderMap = new Dictionary<string, int>(); 

foreach (var element in myList) 
{ 
    orderMap[element] = myList.IndexOf(element); 
} 

В принципе, я хочу взять список, как:

Apple 
Banana 
Orange 

и вернуть карту, показывающую индексы:

Apple -> 0 
Banana -> 1 
Orange -> 2 

Как могу ли я сделать это с Linq? Я думаю, что-то вроде этого должно работать:

orderMap = myList.Select(x => /* return a key value pair mapping x to myList.IndexOf(x) */); 

Но я не могу понять правильный синтаксис для него. Кроме того, можете ли вы обратиться к самому списку в делегате, который используется для Select?

ответ

6

Пока вы можете обратиться к списку в пределах делегата, это вообще не хорошая идея. Вы действительно хотите использовать перегрузку Select, который обеспечивает индекс, а также значение:

var dictionary = list.Select((value, index) => new { value, index }) 
        .ToDictionary(p => p.value, p => p.index); 

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

3

Вы можете попробовать метод ToDictionary расширения:

int index = 0; 
orderMap = myList.ToDictionary(x => x, x => index++); 
+2

Ick, побочные эффекты в селекторе? Нет спасибо :) Я понимаю, что в этом случае он использует немедленную оценку и * будет * работать, но это все равно то, чего я лично избегу. –

+0

Это выбирает индекс как ключ, но OP хочет, чтобы строка была ключевой. –

+0

@JonSkeet Я знаю, что это не самое чистое решение. Я всегда забываю, что полезная перегрузка 'Select' :) @ L.B Спасибо, исправлено это. неверный вопрос. – Botz3000

0

Взгляните на this overload of ToDictionary<TKey, TValue>(). Он принимает функции для преобразования входного элемента в ключ и значение.

например.

var myList = new List<string>{ /* populate list */ }; 
var orderMap = myList.ToDictionary(x => myList.IndexOf(x), x => x); 

Однако одна проблема состоит в том, если элементы myList не являются уникальными.

+0

Это будет работать в O (n^2 * log (n)), тогда как два других ответа выполняются в O (n * log (n)), так как 'IndexOf()' будет сканировать список. –

Смежные вопросы