为了账号安全,请及时绑定邮箱和手机立即绑定

从数组生成条带索引块

从数组生成条带索引块

白猪掌柜的 2023-08-05 21:13:13
我有一个长度为n的数组,我想生成一个新数组作为其索引列表,以便索引被“条带”成块。我所说的“条带化”是指我们将以增量方式多次从 AZ 向上移动索引,并保留模式化的顺序。例如,假设我们的数组有 30 个元素,索引为 0-29。我希望能够提供一个整数作为一个因素,说明我希望条纹如何“混合”;我希望索引重新排序到多少个块中。因子 1(将索引重新排序为 1 个块 - 显然什么也没有发生)[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,27,28,29]因子 2(将索引重新排序为 2 个条带块)[0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,  1,3,5,7,9,11,13,15,17,19,21,23,25,27,29]因子 4(重新排序为 4 个块)[0,4,8,12,16,20,24,28,  1,5,9,13,17,21,25,29,  2,6,10,14,18,22,26,  3,7,11,15,19,23,27]因素7[0,7,14,21,28,  1,8,15,22,29,  2,9,16,23,  3,10,17,24,  4,11,18,25,  5,12,19,26,  6,13,20,27]我不需要对原始数组重新排序,甚至不需要完整地生成这个重新排序的列表 - 我只需要循环现有的数组项并计算出它们的索引将它们放在这个理论上的重新排序列表中的位置。显然,该函数应该适用于任何长度的数组和任何块因子(只要它是整数)。一个关键的事情是,如果 ,则块长度将会不同n % f !== 0。以上面的因子 4 列表为例,其中有两个包含 8 个索引的块和两个包含 7 个索引的块。类似地,对于因子 7 列表,我们得到两个包含 5 个索引的块和五个包含 4 个索引的块。我们可以很快地解决几件事:const perGroup                    = arrayLength / blockSize;const largeGroupCount             = arrayLength % blockSize;const indexThatSmallGroupsStartAt = largeGroupCount * Math.ceil(perGroup);问题是 -我如何从这一点到达完成的功能?我是其中的一部分,但我认为我把它过于复杂化了,需要一双新的眼睛(或大脑)来帮助我完成它!for (i = 0; i < originalArray.length; i++){  const groupSize = i < indexThatSmallGroupsStartAt ? Math.ceil(perGroup) : Math.floor(perGroup);  const newIndex = ???}我一直在尝试计算出目前的组号以及新组中索引的位置,但我不完全确定其中之一或两者都是必要的......(因此上面省略了这段代码)我之所以将索引“条带化”到像这样不断增加的组中,是因为它们将用于从光谱中提取颜色。因此,您可以想象每个组都将遍历整个颜色光谱,但任何后续组中的每个元素都将从前一组中的元素原本所在的位置沿着光谱增量移动。我有一系列需要颜色的东西,以及一个已经存在的函数,可以从我的光谱中提取一系列颜色。因此,我想循环原始数组中的每个项目,并使用 newIndex 从颜色数组中获取颜色。
查看完整描述

2 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

您可以采用一个组装零件的函数。


function getParts(length, parts) {

    return Array

        .from(

            { length: parts },

            (_, i) => Array.from(

                { length: Math.floor(length / parts) + (i < length % parts) },

                (_, j) => i + j * parts

            )

        )

        .flat();

}


console.log(...getParts(10, 2));

console.log(...getParts(10, 7));


查看完整回答
反对 回复 2023-08-05
?
噜噜哒

TA贡献1784条经验 获得超7个赞

您只需重置循环计数器即可按顺序填充数组。


function stripe(length, blocks) {

  let a = new Array(length);

  let i = 0;

  for (let j = 0; i < length; ++j)

    for (let k = j; k < length; k += blocks)

      a[i++] = k;

  return a;

}


console.log(...stripe(30,1))

console.log(...stripe(30,2))

console.log(...stripe(30,4))

console.log(...stripe(30,7))


查看完整回答
反对 回复 2023-08-05
  • 2 回答
  • 0 关注
  • 109 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信