如何使用线性索引在多维数组中设置值 [英] How to set values in a multidimensional array using a linear index

查看:53
本文介绍了如何使用线性索引在多维数组中设置值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用线性索引在C#多维数组中设置值的最有效方法是什么?例如给定一个数组...

What is the most efficient way of setting values in C# multi-dimensional arrays using a linear index? For example given an array...

int[,,] arr2 = {   {{0,1,2}, {3,4,5}, {6,7,8}}
                , {{9,10,11}, {12,13,14}, {15,16,17}}
                , {{18,19,20}, {21,22,23}, {24,25,26}}
        };

如何使用线性索引将所有元素设置为30 ...

How do I set all the elements to 30 using a linear index ...

//This code does not work
for (int i = 0; i < arr.Length; i++)
{
    arr.SetValue(30, i);
}

显然,上面的SetValue()不适用于多维数组.

Apparently the SetValue() above does not work with multidimensional arrays.

这是我能想到的最好的解决方案...

Here is the best solution that I could come up with...

在代码中添加了一些说明...

Added some clarifications to the code...

static class Program
{
    static void Main(string[] args)
    {
        //Sample input. 
        int[,,] arr2 = {   {{0,1,2}, {3,4,5}, {6,7,8}}
                        , {{9,10,11}, {12,13,14}, {15,16,17}}
                        , {{18,19,20}, {21,22,23}, {24,25,26}}
                };

        int[] arr1 = { 1, 2, 3, 4 };

        setElementsTo30(arr2);
        setElementsTo30(arr1);

    }

    //Must be able to process int arrays of arbitrary dimensions and content
    private static void setElementsTo30(Array arr)
    {
        IList<int> cumulativeLength = getCumulativeLengths(arr);

        for (int i = 0; i < arr.Length; i++)
        {
            SetValue(arr, i, 30, cumulativeLength);
        }
    }

    public static void SetValue(this Array arr, int index, object value, IList<int> cumulativeLength)
    {
        int[] arrayIndex = new int[arr.Rank];

        for (int dim = arr.Rank-1; dim >= 0; dim--)
        {
            arrayIndex[dim] = index / cumulativeLength[dim] % arr.GetLength(dim);
        }

        arr.SetValue(value, arrayIndex);
    }

    private static IList<int> getCumulativeLengths(Array arr)
    {
        List<int> lengths = new List<int>(arr.Rank);

        for (int dim = 0; dim < arr.Rank; dim++)
        {
            int prod = 1;
            for (int i = dim + 1; i < arr.Rank; i++)
            {
                prod *= arr.GetLength(i);
            }
            lengths.Add(prod);
        }

        return (IList<int>)lengths;
    }
}

有没有一种方法可以更有效地执行此操作,并且有可能使用框架本身提供的某些功能(即可以轻松使用的功能)

Is there a way to do the same more efficiently and possibly using something provided by the framework itself (i.e. something which can be used without much hassle.)

谢谢,
SDX2000.

Thanks,
SDX2000.

推荐答案

为什么需要IList?

why do you need the IList ?

static void SetValue2(this Array a, object value, int i) {
    int[] indices = new int[a.Rank];
    for (int d = a.Rank - 1; d >= 0; d--) {
        var l = a.GetLength(d);
        indices[d] = i % l;
        i /= l
    }
    a.SetValue(value, indices);
}

测试代码:

static void Main(string[] args) {
    int[, ,] arr2 = {   
        {{0,1,2}, {3,4,5}, {6,7,8}}, 
        {{9,10,11}, {12,13,14}, {15,16,17}}, 
        {{18,19,20}, {21,22,23}, {24,25,26}}
    };
    for (int i = 0; i < arr2.Length; i++) {
        arr2.SetValue2(30, i);
    }
}

这篇关于如何使用线性索引在多维数组中设置值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆