简体   繁体   English

linq ToArray()更改数组长度

[英]linq ToArray() changes array length

Consider the following: 考虑以下:

Dictionary<int,int> dict = new Dictionary<int,int>();
dict.Add(1, 3);
dict.Add(3, 4);

int [] a = new int [] { 1, 2, 3 };
int [] b = new int [a.Length];

Console.WriteLine("a:");
a.Dump(); //using linqpad here

Console.WriteLine("b:");
b.Dump(); //using linqpad here

b = dict.OrderByDescending(x => x.Value).Select(x => x.Key).ToArray();
Console.WriteLine("b after linq:");
b.Dump(); //using linqpad here

RESULTS 结果

a: 1 2 3

b: 0 0 0

b after linq: 3 1 

I have an existing array a . 我有一个现有的阵列a I create an new array of the same length b . 我创建了一个相同长度b的新数组。 After linq query with ToArray() values are added to new array b , but the length changes. 使用ToArray()进行linq查询后, ToArray()值添加到新数组b ,但是长度会更改。 Is there a way to retain the original array length while still adding the values to it? 有没有办法在保留原始数组长度的同时又向其中添加值呢?

DESIRED RESULT 期望的结果

b after linq: 3 1 0

This is an assignment operation: 这是一个分配操作:

b = dict.OrderByDescending(x => x.Value).Select(x => x.Key).ToArray();

it replaces reference to array new int [a.Length] which you have in variable b with new reference to array created by LINQ query. 它用LINQ查询创建的数组的新引用替换对变量b具有的数组new int [a.Length]引用。 Assignment will not change values in the first array. 分配不会更改第一个数组中的值。

If you want to 'merge' two arrays by replacing corresponding items from first array with items from the second array, you can create custom extension method (there is no default LINQ extension for that): 如果要通过将第一个数组中的对应项替换为第二个数组中的项来“合并”两个数组,则可以创建自定义扩展方法(该方法没有默认的LINQ扩展名):

public static IEnumerable<T> MergeWith<T>(
    this IEnumerable<T> source, IEnumerable<T> replacement)
{
    using (var sourceIterator = source.GetEnumerator())
    using (var replacementIterator = replacement.GetEnumerator())
    {
        while (sourceIterator.MoveNext())
            yield return replacementIterator.MoveNext()
                ? replacementIterator.Current
                : sourceIterator.Current;

        // you can remove this loop if you want to preserve source length
        while (replacementIterator.MoveNext())
            yield return replacementIterator.Current;
    }
}

Usage: 用法:

b = b.MergeWith(dict.OrderByDescending(x => x.Value).Select(x => x.Key)).ToArray();

Output: 输出:

b after linq: 3 1 0

As already posted by Sergey, you are reassigning the content of b with your Linq statement. 正如Sergey已经发布的那样,您正在用Linq语句重新分配b的内容。 If you want to fill the rest of the array with zeroes up to a given number use this after the Linq statement: 如果要用零填充数组的其余部分直到给定数字,请在Linq语句后使用以下代码:

Array.Resize(ref b, a.Length);

This way you get your desired result 3 1 0 这样,您将获得所需的结果3 1 0

Note that this operation creates a new array and replaces the existing variable b with this array. 请注意,此操作将创建一个新数组,并用该数组替换现有变量b

You only add "3" and "1" to your dictionary. 您只需在字典中添加“ 3”和“ 1”。 If you want "3 1 0" as result you will need to add a "0" to the dictionary, too. 如果您希望结果为“ 3 1 0”,则还需要在字典中添加“ 0”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM