移动类型 Javascript 数组的值?
Shift values of typed Javascript array?
我有一个类型化的 Javascript 数组 (Float32Array
),我想在数组的开头一次插入一个值,并将所有其他值移动一个位置(最后一个值被删除)。
这是一个例子:
假设我已经初始化了大小为 3 的数组。
该数组当前包含值 [2.0, 7.2, 4.5]
,我想插入数字 8.1
。结果应该是 [8.1, 2.0, 7.2]
.
如果我使用普通的 JS 数组,这没问题——我可以使用像 .unshift()
或 .pop()
这样的函数,但这些方法不适用于类型化的 JS 数组,因为它们会改变数组的大小.
有没有一种方法可以使用类型化 Javascript 数组有效地实现这一点?
您可以通过将末尾的所有值向右移动 1 来“取消移动”固定数组上的值。完成后,只需将 head 替换为 value 参数即可。传统的 for-loops 将是最有效的方法。
这里的关键是向后循环,用左边的邻居填充最后一个槽。
适用于所有 indexed collections:
Array
Int8Array
、Uint8Array
、Uint8ClampedArray
Int16Array
、Uint16Array
Int32Array
、Uint32Array
Float32Array
, Float64Array
BigInt64Array
、BigUint64Array
如您所知,TypedArray 对象不具备标准 Array
对象的所有可用方法。
const shiftRight = (collection, value) => {
for (let i = collection.length - 1; i > 0; i--) {
collection[i] = collection[i - 1]; // Shift right
}
collection[0] = value; // Place new value at head
return collection;
}
const shiftLeft = (collection, value) => {
for (let i = 0; i < collection.length - 1; i++) {
collection[i] = collection[i + 1]; // Shift left
}
collection[collection.length - 1] = value; // Place new value at tail
return collection;
}
const float32 = new Float32Array([2.0, 7.2, 4.5]);
console.log(shiftRight(float32, 8.1)); // >>> [ 8.1, 2.0, 7.2 ]
console.log(shiftLeft(float32, 4.5)); // <<< [ 2.0, 7.2, 4.5 ]
.as-console-wrapper { top: 0; max-height: 100% !important; }
通常你不想用额外的方法污染原型,但如果你到处调用它,你可以设计如下:
shiftRight=(c,v)=>{for(i=c.length-1;i>0;i--)c[i]=c[i-1];c[0]=v;return c}
shiftLeft=(c,v)=>{for(i=0;i<c.length-1;i++)c[i]=c[i+1];c[c.length-1]=v;return c}
/* Needs to be added to all the various indexed collections */
if (Float32Array.prototype.shiftRight === undefined) {
Float32Array.prototype.shiftRight = function(value) {
return shiftRight(this, value);
};
}
if (Float32Array.prototype.shiftLeft === undefined) {
Float32Array.prototype.shiftLeft = function(value) {
return shiftLeft(this, value);
};
}
const float32 = new Float32Array([2.0, 7.2, 4.5]);
console.log([...float32.shiftRight(8.1).values()]); // >>> [ 8.1, 2.0, 7.2 ]
console.log([...float32.shiftLeft(4.5).values()]); // <<< [ 2.0, 7.2, 4.5 ]
.as-console-wrapper { top: 0; max-height: 100% !important; }
这是一个不涉及使用循环的方法(在你这边)。
- 使用子数组使用相同的底层 ArrayBuffer 而不是分配新缓冲区
- 与 Polywhirl 先生相比,这两个函数只是将值移动任意数量的步骤,不涉及插入任何值,因为我认为这也可以使其他用例受益,并使这两个函数更多“纯的”。所以它更适合名字 shift Left/Right
- 子数组+集合+填充faster/more内存友好吗?我不知道
const shiftRight = (collection, steps = 1) => {
collection.set(collection.subarray(0, -steps), steps)
collection.fill(0, 0, steps)
return collection
}
const shiftLeft = (collection, steps = 1) => {
collection.set(collection.subarray(steps))
collection.fill(0, -steps)
return collection
}
const float32 = new Float32Array([2.0, 7.2, 4.5]);
shiftRight(float32) // >>> [ 0, 2.0, 7.2 ]
float32[0] = 8.1 // [ 8.1, 2.0, 7.2 ] Place new value at head
console.log(float32)
shiftLeft(float32) // <<< [ 2.0, 7.2, 0 ]
float32.fill(4.5, -1) // [ 2.0, 7.2, 4.5 ] Place new value at tail
console.log(float32)
shiftRight(float32, 2) // >>> [ 0, 0, 2.0 ] shift right 2 steps
console.log(float32)
我有一个类型化的 Javascript 数组 (Float32Array
),我想在数组的开头一次插入一个值,并将所有其他值移动一个位置(最后一个值被删除)。
这是一个例子:
假设我已经初始化了大小为 3 的数组。
该数组当前包含值 [2.0, 7.2, 4.5]
,我想插入数字 8.1
。结果应该是 [8.1, 2.0, 7.2]
.
如果我使用普通的 JS 数组,这没问题——我可以使用像 .unshift()
或 .pop()
这样的函数,但这些方法不适用于类型化的 JS 数组,因为它们会改变数组的大小.
有没有一种方法可以使用类型化 Javascript 数组有效地实现这一点?
您可以通过将末尾的所有值向右移动 1 来“取消移动”固定数组上的值。完成后,只需将 head 替换为 value 参数即可。传统的 for-loops 将是最有效的方法。
这里的关键是向后循环,用左边的邻居填充最后一个槽。
适用于所有 indexed collections:
Array
Int8Array
、Uint8Array
、Uint8ClampedArray
Int16Array
、Uint16Array
Int32Array
、Uint32Array
Float32Array
,Float64Array
BigInt64Array
、BigUint64Array
如您所知,TypedArray 对象不具备标准 Array
对象的所有可用方法。
const shiftRight = (collection, value) => {
for (let i = collection.length - 1; i > 0; i--) {
collection[i] = collection[i - 1]; // Shift right
}
collection[0] = value; // Place new value at head
return collection;
}
const shiftLeft = (collection, value) => {
for (let i = 0; i < collection.length - 1; i++) {
collection[i] = collection[i + 1]; // Shift left
}
collection[collection.length - 1] = value; // Place new value at tail
return collection;
}
const float32 = new Float32Array([2.0, 7.2, 4.5]);
console.log(shiftRight(float32, 8.1)); // >>> [ 8.1, 2.0, 7.2 ]
console.log(shiftLeft(float32, 4.5)); // <<< [ 2.0, 7.2, 4.5 ]
.as-console-wrapper { top: 0; max-height: 100% !important; }
通常你不想用额外的方法污染原型,但如果你到处调用它,你可以设计如下:
shiftRight=(c,v)=>{for(i=c.length-1;i>0;i--)c[i]=c[i-1];c[0]=v;return c}
shiftLeft=(c,v)=>{for(i=0;i<c.length-1;i++)c[i]=c[i+1];c[c.length-1]=v;return c}
/* Needs to be added to all the various indexed collections */
if (Float32Array.prototype.shiftRight === undefined) {
Float32Array.prototype.shiftRight = function(value) {
return shiftRight(this, value);
};
}
if (Float32Array.prototype.shiftLeft === undefined) {
Float32Array.prototype.shiftLeft = function(value) {
return shiftLeft(this, value);
};
}
const float32 = new Float32Array([2.0, 7.2, 4.5]);
console.log([...float32.shiftRight(8.1).values()]); // >>> [ 8.1, 2.0, 7.2 ]
console.log([...float32.shiftLeft(4.5).values()]); // <<< [ 2.0, 7.2, 4.5 ]
.as-console-wrapper { top: 0; max-height: 100% !important; }
这是一个不涉及使用循环的方法(在你这边)。
- 使用子数组使用相同的底层 ArrayBuffer 而不是分配新缓冲区
- 与 Polywhirl 先生相比,这两个函数只是将值移动任意数量的步骤,不涉及插入任何值,因为我认为这也可以使其他用例受益,并使这两个函数更多“纯的”。所以它更适合名字 shift Left/Right
- 子数组+集合+填充faster/more内存友好吗?我不知道
const shiftRight = (collection, steps = 1) => {
collection.set(collection.subarray(0, -steps), steps)
collection.fill(0, 0, steps)
return collection
}
const shiftLeft = (collection, steps = 1) => {
collection.set(collection.subarray(steps))
collection.fill(0, -steps)
return collection
}
const float32 = new Float32Array([2.0, 7.2, 4.5]);
shiftRight(float32) // >>> [ 0, 2.0, 7.2 ]
float32[0] = 8.1 // [ 8.1, 2.0, 7.2 ] Place new value at head
console.log(float32)
shiftLeft(float32) // <<< [ 2.0, 7.2, 0 ]
float32.fill(4.5, -1) // [ 2.0, 7.2, 4.5 ] Place new value at tail
console.log(float32)
shiftRight(float32, 2) // >>> [ 0, 0, 2.0 ] shift right 2 steps
console.log(float32)