以功能编程兼容的方式交换C#中的数组键和值

时间:2018-07-11 12:15:11

标签: c# linq functional-programming

假设我有以下C#代码:

var array = new []{3, 2, 5, 4, 1, 0};
var converted = new int[array.Length];
for (var i = 0; i < array.Length; i++) {
    converted[array[i]] = i;
}

然后,最后,我们有converted == new {5, 4, 1, 0, 3, 2};。但是,“ for循环是邪恶的”,因此我可以将其重写如下:

var array = new []{3, 2, 5, 4, 1, 0};
var converted = new int[array.Length];
array
    .Select((value, index) => new {index, value})
    .ToList()
    .ForEach(o => converted[o.value] = o.index);

但是,我们仍然有一个突变状态。 Linq是否提供一种不错的方式来实现此目的,而又不增加渐近复杂性?

我知道我可以根据值进行排序,也可以使用某种搜索技术,但是在两种情况下,复杂度都会达到O(n log n)或更高。

编辑:我知道至少第二个是丑陋的。第一个是通常如何完成这类事情,但是在几乎每种情况下,LINQ都比for循环提供一种更好,更易理解的方法。因此,我想知道LINQ是否有办法做到这一点。

1 个答案:

答案 0 :(得分:1)

您的for循环很好 。不要改变它。有时最好按程序进行操作,而有时最好按功能进行。在这种情况下,程序会更好。

只要看看如果在功能上完成了,那将会是多么可怕的一幕:

// assuming the values are all members of the set of natural numbers from 0 to (array.Length - 1)
var converted = array.Select((x, i) => new { Index = i, Element = x })
                     .OrderBy(x => x.Element)
                     .Select(x => x.Index).ToList();

与程序版本相比,它的可读性要差得多。