array.reverse() 在平面数组中逐块
array.reverse() block-wise in flat array
我正在编写一个像素动画,从 Unit8Array 中读取数据
5 帧,每帧 72 个二进制文件。现在我想反转帧来反转动画。所以我的问题:
有没有办法按块反转,或者有谁有创意,我该怎么做?
(我不能只是 运行 向后,因为每一帧都需要前一帧的信息)
const myArr = [1,2,3,4,5,6,7,8];
console.log(myArr.reverse());//8,7,6,5,4,3,2,1
//how to reach [7,8,5,6,3,4,1,2]?
//would work fine with 2D array,
//but don't have 2D
const my2D = [[1,2],[3,4],[5,6],[7,8]];
应该这样做:
const reversed = myArr
.map((_, i, a) => a[i ^ 1])
.reverse()
它的工作方式是将每个数组元素映射到另一个元素,并通过使用 XOR 反转 1 位来更改索引(例如 4^1=5、5^1=4、6^1=7 , 7^1=6, 等等) 然后反转整个数组.
此技巧可用于任何 2 的幂:您可以使用 ^ 3
翻转 1 位和 2 位反转 4 个元素组,使用 ^ 7
翻转 4 位反转 8 个元素组, 2 和 1 位等等。 (如果您需要其他组大小,则必须使用更昂贵的操作,例如 i + size - 1 - 2 * (i % size)
。)
map
使用几个参数调用回调 - 第一个是元素的值,但我们真的不需要它,所以我们将它分配给一个未使用的变量 _
.第二个是索引,第三个是数组本身。实际上我们只需要索引,但是使用第三个参数我们可以避免在行中写两次数组的名称(myArr.map((_, i) => myArr[i ^ 1])
也可以)。
注意:根据您的确切用例,另一种选择可能是在 访问 数据时对索引执行 array.length - i ^ 1
操作,而不是创建新的索引数组。
受 CherryDT 的回答启发,一次 map
调用即可完成:
const arr = [1,2,3,4,5,6,7,8];
console.log(
arr.map((_, i) => arr[arr.length - i - 1 ^ 1])
);
我正在编写一个像素动画,从 Unit8Array 中读取数据 5 帧,每帧 72 个二进制文件。现在我想反转帧来反转动画。所以我的问题:
有没有办法按块反转,或者有谁有创意,我该怎么做? (我不能只是 运行 向后,因为每一帧都需要前一帧的信息)
const myArr = [1,2,3,4,5,6,7,8];
console.log(myArr.reverse());//8,7,6,5,4,3,2,1
//how to reach [7,8,5,6,3,4,1,2]?
//would work fine with 2D array,
//but don't have 2D
const my2D = [[1,2],[3,4],[5,6],[7,8]];
应该这样做:
const reversed = myArr
.map((_, i, a) => a[i ^ 1])
.reverse()
它的工作方式是将每个数组元素映射到另一个元素,并通过使用 XOR 反转 1 位来更改索引(例如 4^1=5、5^1=4、6^1=7 , 7^1=6, 等等) 然后反转整个数组.
此技巧可用于任何 2 的幂:您可以使用 ^ 3
翻转 1 位和 2 位反转 4 个元素组,使用 ^ 7
翻转 4 位反转 8 个元素组, 2 和 1 位等等。 (如果您需要其他组大小,则必须使用更昂贵的操作,例如 i + size - 1 - 2 * (i % size)
。)
map
使用几个参数调用回调 - 第一个是元素的值,但我们真的不需要它,所以我们将它分配给一个未使用的变量 _
.第二个是索引,第三个是数组本身。实际上我们只需要索引,但是使用第三个参数我们可以避免在行中写两次数组的名称(myArr.map((_, i) => myArr[i ^ 1])
也可以)。
注意:根据您的确切用例,另一种选择可能是在 访问 数据时对索引执行 array.length - i ^ 1
操作,而不是创建新的索引数组。
受 CherryDT 的回答启发,一次 map
调用即可完成:
const arr = [1,2,3,4,5,6,7,8];
console.log(
arr.map((_, i) => arr[arr.length - i - 1 ^ 1])
);