Получение ключа массива в цикле "foreach"
Как получить ключ текущего элемента в цикле foreach
на С#?
Например:
PHP
foreach ($array as $key => $value)
{
echo("$value is assigned to key: $key");
}
Что я пытаюсь сделать в С#:
int[] values = { 5, 14, 29, 49, 99, 150, 999 };
foreach (int val in values)
{
if(search <= val && !stop)
{
// Set key to a variable
}
}
Ответы
Ответ 1
Способ Grauenwolf - это самый простой и эффективный способ сделать это с помощью массива:
Либо используйте цикл for, либо создайте временную переменную, которую вы увеличиваете на каждом проходе.
Что бы, конечно, выглядело так:
int[] values = { 5, 14, 29, 49, 99, 150, 999 };
for (int key = 0; key < values.Length; ++key)
if (search <= values[key] && !stop)
{
// set key to a variable
}
С .NET 3.5 вы можете использовать более функциональный подход, но он немного более подробен на сайте и, вероятно, будет полагаться на пару функции поддержки для посещать элементы в IEnumerable. Overkill, если это все, что вам нужно для этого, но удобно, если вы склонны много обрабатывать сбор.
Ответ 2
Если вы хотите получить ключ (read: index), вам придется использовать цикл for. Если вы действительно хотите иметь коллекцию, содержащую ключи/значения, я бы подумал об использовании HashTable или Dictionary (если вы хотите использовать Generics).
Dictionary<int, string> items = new Dictionary<int, string>();
foreach (int key in items.Keys)
{
Console.WriteLine("Key: {0} has value: {1}", key, items[key]);
}
Надеюсь, что это поможет,
Тайлер
Ответ 3
С DictionaryEntry и KeyValuePair:
Основываясь на
MSDN
IDictionary<string,string> openWith = new Dictionary<string,string>()
{
{ "txt", "notepad.exe" }
{ "bmp", "paint.exe" }
{ "rtf", "wordpad.exe" }
};
foreach (DictionaryEntry de in openWith)
{
Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
}
// also
foreach (KeyValuePair<string,string> de in openWith)
{
Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
}
Вышел вопрос SO: KeyValuePair VS DictionaryEntry
Ответ 4
Увы, нет встроенного способа сделать это. Либо используйте цикл for, либо создайте временную переменную, которую вы увеличиваете на каждом проходе.
Ответ 5
Я ответил на это в другой версии этого вопроса:
Foreach предназначен для итерации коллекции, которые реализуют IEnumerable. Он делает это, позвонив GetEnumerator в коллекции, которая вернет Enumerator.
В этом перечислителе есть метод и Свойство:
* MoveNext()
* Current
Current возвращает объект, который В настоящее время перечислитель включен, MoveNext Обновляет текущий до следующего объекта.
Очевидно, что понятие индекса за исключением концепции перечисления, и не может быть сделано.
Из-за этого большинство коллекций может быть пройден с использованием индексатора и конструкцию цикла цикла.
Я предпочитаю использовать цикл for в эта ситуация по сравнению с отслеживанием индекс с локальной переменной.
Как получить индекс текущей итерации цикла foreach?
Ответ 6
На самом деле вы должны использовать классический цикл for (;;), если вы хотите перебирать массив. Но аналогичная функциональность, которую вы достигли с помощью вашего PHP-кода, может быть достигнута на С#, например, с помощью словаря:
Dictionary<int, int> values = new Dictionary<int, int>();
values[0] = 5;
values[1] = 14;
values[2] = 29;
values[3] = 49;
// whatever...
foreach (int key in values.Keys)
{
Console.WriteLine("{0} is assigned to key: {1}", values[key], key);
}
Ответ 7
Вот решение, которое я только что придумал для этой проблемы
Исходный код:
int index=0;
foreach (var item in enumerable)
{
blah(item, index); // some code that depends on the index
index++;
}
Обновленный код
enumerable.ForEach((item, index) => blah(item, index));
Метод расширения:
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumerable, Action<T, int> action)
{
var unit = new Unit(); // unit is a new type from the reactive framework (http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx) to represent a void, since in C# you can't return a void
enumerable.Select((item, i) =>
{
action(item, i);
return unit;
}).ToList();
return pSource;
}
Ответ 8
Вы можете реализовать эту функцию самостоятельно, используя метод расширения. Например, вот реализация метода расширения KeyValuePairs, который работает в списках:
public struct IndexValue<T> {
public int Index {get; private set;}
public T Value {get; private set;}
public IndexValue(int index, T value) : this() {
this.Index = index;
this.Value = value;
}
}
public static class EnumExtension
{
public static IEnumerable<IndexValue<T>> KeyValuePairs<T>(this IList<T> list) {
for (int i = 0; i < list.Count; i++)
yield return new IndexValue<T>(i, list[i]);
}
}
Ответ 9
myKey = Array.IndexOf(values, val);