在 C# .NET 2.0 中,反向执行 foreach 的简单方法是什么?

发布于 2024-07-05 14:44:25 字数 358 浏览 2 评论 0原文

假设我有一个 Dictionary 对象:

Dictionary myDictionary<int, SomeObject> = new Dictionary<string, SomeObject>();

现在我想以相反的顺序迭代字典。 我无法使用简单的 for 循环,因为我不知道字典的键。 foreach 很简单:

foreach (SomeObject object in myDictionary.Values)
{
    // Do stuff to object
}

但是我怎样才能反向执行这个操作呢?

Lets say I have a Dictionary object:

Dictionary myDictionary<int, SomeObject> = new Dictionary<string, SomeObject>();

Now I want to iterate through the dictionary in reverse order. I can't use a simple for loop because I don't know the keys of the dictionary. A foreach is easy:

foreach (SomeObject object in myDictionary.Values)
{
    // Do stuff to object
}

But how can I perform this in reverse?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

你怎么这么可爱啊 2024-07-12 14:44:25

字典或任何其他形式的哈希表没有顺序。 所以你想做的事情是毫无意义的:)

A dictionary or any other form of hashtable has no ordering. So what you are trying to do is pointless :)

后知后觉 2024-07-12 14:44:25

我会使用 SortedList 而不是字典。 您仍然可以通过 Key 访问它,但也可以通过索引访问它。

SortedList sCol = new SortedList();

sCol.Add("bee", "Some extended string matching bee");
sCol.Add("ay", "value matching ay");
sCol.Add("cee", "Just a standard cee");

// Go through it backwards.
for (int i = sCol.Count - 1; i >=0 ; i--)
    Console.WriteLine("sCol[" + i.ToString() + "] = " + sCol.GetByIndex(i));

// Reference By Key
foreach (string i in sCol.Keys)
    Console.WriteLine("sCol[" + i + "] = " + sCol[i]);

// Enumerate all values
foreach (string i in sCol.Values)
    Console.WriteLine(i);

值得注意的是,排序列表存储仅按键排序的键/值对。

I'd use a SortedList instead of a dictionary. You can still access it by Key, but you can access it by index as well.

SortedList sCol = new SortedList();

sCol.Add("bee", "Some extended string matching bee");
sCol.Add("ay", "value matching ay");
sCol.Add("cee", "Just a standard cee");

// Go through it backwards.
for (int i = sCol.Count - 1; i >=0 ; i--)
    Console.WriteLine("sCol[" + i.ToString() + "] = " + sCol.GetByIndex(i));

// Reference By Key
foreach (string i in sCol.Keys)
    Console.WriteLine("sCol[" + i + "] = " + sCol[i]);

// Enumerate all values
foreach (string i in sCol.Values)
    Console.WriteLine(i);

It's worth noting that a sorted list stores key/value pairs sorted by key only.

请恋爱 2024-07-12 14:44:25

如果您有.NET 3.5,则可以在 IEnumerables 上使用 .Reverse() 扩展方法。 例如:

foreach (object o in myDictionary.Values.Reverse())
{
     // Do stuff to object
}

If you have .NET 3.5 you can use the .Reverse() extension method on IEnumerables. For example:

foreach (object o in myDictionary.Values.Reverse())
{
     // Do stuff to object
}
甜柠檬 2024-07-12 14:44:25

实际上,在 C# 2.0 中,您可以创建自己的迭代器来反向遍历容器。 然后,您可以在 foreach 语句中使用该迭代器。 但是你的迭代器首先必须有一种导航容器的方法。 如果它是一个简单的数组,它可以像这样向后移动:

static IEnumerable<T> CreateReverseIterator<T>(IList<T> list)
{
    int count = list.Count;
    for (int i = count - 1; i >= 0; --i)
    {
        yield return list[i];
    }
}

但是当然你不能用字典来做到这一点,因为它没有实现 IList 或提供索引器。 说字典没有顺序是不正确的:它当然有顺序。 如果您知道它是什么,那么该命令甚至会很有用。

为了解决您的问题:我想说将元素复制到数组中,然后使用上述方法反向遍历它。 像这样:

static void Main(string[] args)
{
    Dictionary<int, string> dict = new Dictionary<int, string>();

    dict[1] = "value1";
    dict[2] = "value2";
    dict[3] = "value3";

    foreach (KeyValuePair<int, string> item in dict)
    {
        Console.WriteLine("Key : {0}, Value: {1}", new object[] { item.Key, item.Value });
    }

    string[] values = new string[dict.Values.Count];
    dict.Values.CopyTo(values, 0);

    foreach (string value in CreateReverseIterator(values))
    {
        Console.WriteLine("Value: {0}", value);
    }

}

将值复制到数组似乎是一个坏主意,但根据值的类型,它实际上并没有那么糟糕。 您可能只是复制参考资料!

Actually, in C# 2.0 you can create your own iterator that traverses a container in reverse. Then, you can use that iterator in your foreach statement. But your iterator would have to have a way of navigating the container in the first place. If it's a simple array, it could go backwards like this:

static IEnumerable<T> CreateReverseIterator<T>(IList<T> list)
{
    int count = list.Count;
    for (int i = count - 1; i >= 0; --i)
    {
        yield return list[i];
    }
}

But of course you can't do that with a Dictionary as it doesn't implement IList or provides an indexer. Saying that a Dictionary does not have order is not true: of course it has order. That order can even be useful if you know what it is.

For a solution to your problem: I'd say copy the elements to an array, and use the above method to traverse it in reverse. Like this:

static void Main(string[] args)
{
    Dictionary<int, string> dict = new Dictionary<int, string>();

    dict[1] = "value1";
    dict[2] = "value2";
    dict[3] = "value3";

    foreach (KeyValuePair<int, string> item in dict)
    {
        Console.WriteLine("Key : {0}, Value: {1}", new object[] { item.Key, item.Value });
    }

    string[] values = new string[dict.Values.Count];
    dict.Values.CopyTo(values, 0);

    foreach (string value in CreateReverseIterator(values))
    {
        Console.WriteLine("Value: {0}", value);
    }

}

Copying your values to an array may seem like a bad idea, but depending on the type of value it's not really that bad. You might just be copying references!

梦在夏天 2024-07-12 14:44:25

我同意@leppie,但认为你应该得到这个问题的总体答案。 可能您的本意是一般性问题,但无意中选择了错误的数据结构。 字典中值的顺序应被视为特定于实现的; 根据文档,它总是与键相同的顺序,但这个顺序也未指定。

无论如何,没有一种简单的方法可以让 foreach 反向工作。 使用类的枚举器是一种语法糖,并且枚举器只能朝一个方向移动。 从技术上讲,答案可能是“反转集合,然后枚举”,但我认为在这种情况下,您只需使用“向后”for 循环:

for (int i = myCollection.Length - 1; i >= 0; i--)
{
    // do something
}

I agree with @leppie, but think you deserve an answer to the question in general. It could be that you meant for the question to be in general, but accidentally picked a bad data structure. The order of the values in a dictionary should be considered implementation-specific; according to the documentation it is always the same order as the keys, but this order is unspecified as well.

Anyway, there's not a straightforward way to make foreach work in reverse. It's syntactic sugar to using the class's enumerator, and enumerators can only travel in one direction. Technically the answer could be "reverse the collection, then enumerate", but I think this is a case where you'll just have to use a "backwards" for loop:

for (int i = myCollection.Length - 1; i >= 0; i--)
{
    // do something
}
冷默言语 2024-07-12 14:44:25

如果您没有 .NET 3.5,因此没有 Reverse 扩展方法,您可以实现自己的方法。 我猜它可能会生成一个中间列表(必要时)并反向迭代它,如下所示:

public static IEnumerable<T> Reverse<T>(IEnumerable<T> items)
{
    IList<T> list = items as IList<T>;
    if (list == null) list = new List<T>(items);
    for (int i = list.Count - 1; i >= 0; i-- )
    {
        yield return list[i];
    }
}

If you don't have .NET 3.5 and therefore the Reverse extension method you can implement your own. I'd guess it probably generates an intermediate list (when necessary) and iterates it in reverse, something like the following:

public static IEnumerable<T> Reverse<T>(IEnumerable<T> items)
{
    IList<T> list = items as IList<T>;
    if (list == null) list = new List<T>(items);
    for (int i = list.Count - 1; i >= 0; i-- )
    {
        yield return list[i];
    }
}
请恋爱 2024-07-12 14:44:25

那将是一个 Dictionary。 myDictionary,你可以通过以下方式做到这一点:

foreach(SomeObject _object in myDictionary.Values.Reverse())
{
}

That would be a Dictionary<int, SomeObject> myDictionary, and you would do it by:

foreach(SomeObject _object in myDictionary.Values.Reverse())
{
}
一紙繁鸢 2024-07-12 14:44:25

我在 .NET 2.0 中能想到的唯一方法是首先将所有值复制到列表中,反转列表,然后在该列表上运行 foreach:

Dictionary<int, object> d;
List<object> tmplist;
foreach (object o in d.Values) tmplist.Add(s);
tmplist.Reverse();
foreach (object o in tmplist) {
    //Do stuff
}

The only way I can come up with in .NET 2.0 is to first copy all the values to a List, reverse the list and then run the foreach on that list:

Dictionary<int, object> d;
List<object> tmplist;
foreach (object o in d.Values) tmplist.Add(s);
tmplist.Reverse();
foreach (object o in tmplist) {
    //Do stuff
}
谁人与我共长歌 2024-07-12 14:44:25

字面答案:

Dictionary<int, SomeObject>  myDictionary = new Dictionary<int, SomeObject>();

foreach (var pair in myDictionary.OrderByDescending(i => i.Key))
{
    //Observe pair.Key
    //Do stuff to pair.Value
}

Literal answer:

Dictionary<int, SomeObject>  myDictionary = new Dictionary<int, SomeObject>();

foreach (var pair in myDictionary.OrderByDescending(i => i.Key))
{
    //Observe pair.Key
    //Do stuff to pair.Value
}
月亮坠入山谷 2024-07-12 14:44:25

如果顺序最重要,您可以创建一个堆栈并创建一个简单的结构来存储 int、对象对。

If the ordering is most important, you could you a Stack and create a simple struct to store your int, Object pair.

梦归所梦 2024-07-12 14:44:25

如果您想要字典类型集合但需要维护插入顺序,您可以查看 KeyedCollection
此处

它是字典和列表的合并。 这样您就可以通过键或插入索引访问集合中的元素。

唯一的问题是存储在集合中的元素是否必须有一个 int 键。 如果您可以将其更改为字符串或其他类型(Guid Mabye)。 由于 collection1 将搜索键 1 而不是指数1。

If you want a dictionary type collection but you need to maintain the insertion order you can look into the KeyedCollection
here

It is a merger between a dictionary and a list. That way you can access elements in the collection via the key or the insertion index.

The only gotcha is if your element being stored in the collection has to have an int key. If you could change that to a string or another type (Guid Mabye). Since collection1 will be searching for the key of 1 rather than the index of 1.

辞旧 2024-07-12 14:44:25

标准的 for 循环是最好的。 您不必担心反转集合的处理开销。

A standard for loop would be best. You don't have to worry about the processing overhead of reversing the collection.

伤感在游骋 2024-07-12 14:44:25

您可以在 .NET 中使用 LINQ to 对象 Enumerable.Reverse() 函数2.0 使用 LinqBridge

You can use the LINQ to Objects Enumerable.Reverse() function in .NET 2.0 using LinqBridge.

独自唱情﹋歌 2024-07-12 14:44:25
foreach (Sample in Samples)

try the following:

Int32 nEndingSample = Samples.Count - 1;

for (i = nEndingSample; i >= 0; i--)
{
     x = Samples[i].x;
     y = Samples[i].y;
}
foreach (Sample in Samples)

try the following:

Int32 nEndingSample = Samples.Count - 1;

for (i = nEndingSample; i >= 0; i--)
{
     x = Samples[i].x;
     y = Samples[i].y;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文