可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
How do I get the key of the current element in a foreach
loop in C#?
For example:
PHP
foreach ($array as $key => $value)
{
echo("$value is assigned to key: $key");
}
What I'm trying to do in C#:
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's way is the most straightforward and performant way of doing this with an array:
Either use a for loop or create a temp variable that you increment on each pass.
Which would of course look like this:
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
}
With .NET 3.5 you can take a more functional approach as well, but it is a little more verbose at the site, and would likely rely on a couple support functions for visiting the elements in an IEnumerable. Overkill if this is all you need it for, but handy if you tend to do a lot of collection processing.
回答2:
If you want to get at the key (read: index) then you'd have to use a for loop. If you actually want to have a collection that holds keys/values then I'd consider using a HashTable or a Dictionary (if you want to use 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]);
}
Hope that helps,
Tyler
回答3:
With DictionaryEntry and KeyValuePair:
Based on
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);
}
Releated SO question: KeyValuePair VS DictionaryEntry
回答4:
Alas there is no built-in way to do this. Either use a for loop or create a temp variable that you increment on each pass.
回答5:
I answered this in another version of this question:
Foreach is for iterating over
collections that implement
IEnumerable. It does this by calling
GetEnumerator on the collection, which
will return an Enumerator.
This Enumerator has a method and a
property:
* MoveNext()
* Current
Current returns the object that
Enumerator is currently on, MoveNext
updates Current to the next object.
Obviously, the concept of an index is
foreign to the concept of enumeration,
and cannot be done.
Because of that, most collections are
able to be traversed using an indexer
and the for loop construct.
I greatly prefer using a for loop in
this situation compared to tracking
the index with a local variable.
How do you get the index of the current iteration of a foreach loop?
回答6:
Actually you should use classic for (;;) loop if you want to loop through an array. But the similar functionality that you have achieved with your PHP code can be achieved in C# like this with a Dictionary:
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:
You can implement this functionality yourself using an extension method. For example, here is an implementation of an extension method KeyValuePairs which works on lists:
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]);
}
}
回答8:
Here's a solution I just came up with for this problem
Original code:
int index=0;
foreach (var item in enumerable)
{
blah(item, index); // some code that depends on the index
index++;
}
Updated code
enumerable.ForEach((item, index) => blah(item, index));
Extension Method:
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;
}
回答9:
myKey = Array.IndexOf(values, val);