javascript - JS 平面对象作为矩阵坐标 : how to init all values?

标签 javascript object matrix initialization coordinates

这是我的代码:

class ArrayND {
    /**
     * @param {Array<number>} ranks
     */
    constructor (ranks) {
        this.coords = {}
        this._ranks = ranks
    }

    /**
     * @param {number|string} defaultValue
     */
    init (defaultValue) {
        // How to init this.coords with defaultValue given this._ranks ?
    }
}

我想要实现的目标:

const myArrayND = new ArrayND([3, 2])
myArrayND.init(5)
/*
myArrayND.coords should be :
{
    0,0: 5,
    0,1: 5,
    1,0: 5,
    1,1: 5,
    2,0: 5,
    2,1: 5
}
*/
myArrayND.coords[[2, 1]] // returns 5

我的问题是:当 ArrayND 可以用任意等级构建时,如何实现 init() 函数?

示例:

const firstArray = new ArrayND([])
firstArray.init(5)
// firstArray.coords contains {}

const secondArray = new ArrayND([5])
secondArray.init('aze')
/* secondArray.coords contains {
    0: 'aze',
    1: 'aze',
    2: 'aze',
    3: 'aze',
    4: 'aze',
} */
const thirdArray = new ArrayND([2, 3])
thirdArray.init(2)
/* thirdArray.coords contains {
    0,0: 2,
    0,1: 2,
    0,2: 2,
    1,0: 2,
    1,1: 2,
    1,2: 2,
} */
const anotherExample = new ArrayND([1, 2, 3])
anotherExample.init(1)
/* anotherExample.coords contains {
    0,0,0: 1,
    0,0,1: 1,
    0,0,2: 1,
    0,1,0: 1,
    0,1,1: 1,
    0,1,2: 1,
} */
...

我不希望 myObject.coords 包含多维数组,因为我在访问和设置多维数组中的值时遇到其他问题:请参阅 JS multidimentional array modify value 。它工作得很好,但丑陋的开关盒非常令人厌恶。

而不是拥有

multiDimArray = [
    [
        [1],
        [2],
        [3]
    ],
    [
        [4],
        [5],
        [6]
    ]
]
multiDimArray[0][1][2] // returns 6

问题在于访问:

function setValue(indexArray, value) {
    switch (indexArray.length) {
        case 0:
           multiDimArray = value
        case 1:
           multiDimArray[indexArray[0]] = value
        case 2:
           multiDimArray[indexArray[0]][indexArray[1]] = value
        case 3:
           multiDimArray[indexArray[0]][indexArray[1]][indexArrat[2]] =value
        ...
        // Very ugly and isn't truly dynamic
    }
}

我要

multiDimArray = {
    0,0,0: 1,
    0,0,1: 2,
    0,0,2: 3,
    0,1,0: 4,
    0,1,1: 5,
    0,1,2: 6,   
}
multiDimArray[[0, 1, 2]] // returns 6

这样我就可以使用这样的函数动态访问和设置值:(在数组数组的情况下,这是用一个丑陋的开关案例完成的)

function setValue(indexArray, value) {
    multiDimArray[indexArray] = value
    // much better than before.
}

所以我知道“ArrayND”这个名字可能有点误导,但它实际上不是一个数组,它是一个包含 n 维数组坐标的平面对象。

最佳答案

如果我理解正确,您始终可以生成 N 维数组并将其初始化如下。最后一个参数是初始化值。前面是dimens数组,其长度是维度数,items是要创建的数组每个维度的大小。

要实例化多维数组,我们必须有一个 Array.prototype.clone() 方法,以防止引用被复制。所以事情是这样的。

Object.prototype.getNestedValue = function(...a) {
  return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};

Array.prototype.clone = function(){
  return this.reduce((p,c,i) => (p[i] = Array.isArray(c) ? c.clone() : c, p),[])
}

function arrayND(...n){
  return n.reduceRight((p,c) => c = (new Array(c)).fill(true).map(e => Array.isArray(p) ? p.clone() : p ));
}


var m = arrayND(...[3,4,2,3],5);
m[0][2][1][2] = "five";

console.log(JSON.stringify(m,null,2));

console.log(m.getNestedValue(2,3,1,2));

你当然可以对 Array.prototype.reduce() 做同样的事情,但为了抽象,我更喜欢从右到左

关于javascript - JS 平面对象作为矩阵坐标 : how to init all values?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37319416/

相关文章:

javascript - 使用 javascript 方法向页面添加框

java - 没有出现 OutOfMemory 错误的最大尺寸矩阵?

javascript - 在 d3.js 中从一个圆圈画一条线到另一个圆圈

javascript - 汇总具有相同属性名称的对象的值

java - 我可以将类包含在与主类相同的源代码中吗?

algorithm - 装箱解决方案 : what's going on with this?

python - 将函数应用于两个形状相同的 numpy 矩阵

javascript - 如何使用回调从带有 node.js 和 ejs 的 mysql 中获取数据?

javascript - 在附加到动态内容中的元素之前删除最后一个 TD

javascript - ASP.NET MVC 从代码块内访问 JavaScript 变量