JavaScript 你有使用过竖着遍历的数组嘛!!!

1,922 阅读6分钟

背景

今天准时到公司座位后,马上收到Leader的信息,改需求,觉得这个需求有点意思,就记录下来和大家分享啦~,开干!!!😆

😺 需求:

image.png

改成下面这种

image.png

这个是大家平时用的比较多的一个Element组件库的 el-descriptions组件,上面的需求是5列改为4列,这个可能就一个属性 column 把他改为 4就可以了对吧。

⚠️注意,请看元素是怎么排列的,他是从上往下的,竖着来排了,大家都知道平时使用 el-descriptions 组件的时候,像这种的话,我们一般是用v-for去遍历 el-descriptions-item 标签。显然,以这种方式去遍历我们会得到上面第一张图的样子。

<el-descriptions border :column="4" title="改成这个样子:">
    <el-descriptions-item v-for="(item, index) in descriptionsList" :key="index" :label="item.label">
        <el-button type="primary" size="mini">{{ item.value }}</el-button>
    </el-descriptions-item>
</el-descriptions>

// data数据:
descriptionsList: [
    { label: "label", value: "我是元素0" },
    { label: "label", value: "我是元素1" },
    { label: "label", value: "我是元素2" },
    { label: "label", value: "我是元素3" },
    ...
]

😺 解决方案:

思考怎么把它变成竖着遍历,不难发现,我们把对应元素位置调换即可

image.png

根据上面导图我们可以得出调换位置的索引顺序

// 原数组
const originalArr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
// 变更数组
const changeArray = [0, 4, 8, 12, 16, 1, 5, 9, 13, 17, 2, 6, 10, 14, 18, 3, 7, 15, 17, 19];

👀怕大家可能看着上面的变更数组索引顺序有点不太明白,所以我贴了下面这张图,供大家更好的理解为什么这样子排。

image.png 我们看第一列, 元素0(原始数组索引0),我们要变更到索引0位置上面;

元素1(原始数组索引1),我们要变更到索引4上面;

元素2(原始数组索引2),我们要变更到索引8上面;

...以此类推,我们就可以推出上面那个数组顺序了

一一对应:

原始位置最终位置
00
14
28
312
416
51
65
79
813
917
102
116
1210
1314
1418
......

😺 规律:

我们一起来看一下这个对应的规律:

0 -> 0

1 -> 4

2 -> 8

3 -> 12

4 -> 16

看上面这个很好发现,他们是对应关系

0 * (4) = 0;

1 * (4) = 4;

2 * (4) = 8;

3 * (4) = 12;

4 * (4) = 16;

😺看到这里,同学们可能会说:“太简单了,*4 就能找到对应位置了”。君子请留步,看我们 索引5 的对应位置是 1,奇了怪,怎么这 *4不管用了呀!

我们接着分析

5 -> 1

6 -> 5

7 -> 9

8 -> 13

9 -> 17

这上面的又有什么规律呢?51有什么关系呢?

// 咱们来除一下看对不对
1 / 5 = 0.2;
5 * 0.2 = 1;   // 成立
6 * 0.2 = 1.2; // 不成立
1.2???不对不对不对!!!

// 那我们来减一下
5 - 4 = 1;   // 成立
6 - 4 = 2;   // 不成立
2??不对不对不对

好像我们找不到什么规律哎!目前有想法的小伙伴可在评论区留言哦

暂时还没想到有什么规律的小伙伴我们接着往下看,我们换个角度,把原索引,和前一组索引来对比,看看有没有漏了什么“蛛丝马迹”😂。

5  6  7  8  9
0  1  2  3  4
// 我们看看上面这两组数据有什么区别
// 眼尖的小伙伴一眼就能看出:被减数 - 减数 = 差
5 - 0 = 5
6 - 1 = 5
7 - 2 = 5
...
// 得出结论:差是 `5`

我们减去5再代入重新试一下

(5 - 5) * 4 (?) = 1;  // 1

(6 - 5) * 4 (?) = 5;  // 5

(7 - 5) * 4 (?) = 9;  // 9

(8 - 5) * 4 (?) = 13; // 13

(9 - 5) * 4 (?) = 17; // 17
// 纳闷了,减去5好像还是不对,还差一点点,这里很明显了,我们问号再+1,等式即可成立
(5 - 5) * 4 + 1 = 1;  // 成立
(6 - 5) * 4 + 1 = 5;  // 成立
...

成功成功,胜利的呼声向我们靠近😉

// 我们接着代入数字
10 -> 2
(10 - 5) * 4 + 1 = 21;  // 不成立

显然我们又再次犯难了,重新和第一组对比一下,或者和第二组对比一下

10 11 12 13 14  // 当前组
5  6  7  8  9   // 第二组
0  1  2  3  4   // 第一组

// 比较明显,列对应的差是5,那当前组和第一组差的就是10,重新套用刚才的公式
(10 - 10) * 4 (?) = 2;
(11 - 10) * 4 (?) = 6; 
(12 - 10) * 4 (?) = 10;
(13 - 10) * 4 (?) = 14;
(14 - 10) * 4 (?) = 18; 
那我们(?)该填什么呢?非常对我们应该 +2 ,等式再次成立

到目前为止,我们应该很清楚的知道,每五个元素他的公式就不一样

第一组*4可以得出结果
第二组-5  * 4 + 1
第三组-10 * 4 + 2
第四组-15 * 4 + 3
由后面三组我们可以推导出第一组应该是:-0 * 4 + 0
第一个关键值就是是-的,`0 5 10 15`,递增 `5`
中间的关键值没变都是 `*4`
最后一个关键值:`0 1 2 3`这种就比较明显了顺序排列 递增 `1`
....

🐱 公式/代码

最后我们来写一下公式,直接上代码

// (i % 5) * 4 + Math.floor(i / 5);
// 公式中的第一关键点 `%5` 是为了让这个值变回到和第一组一样的值进行处理,*4这里大家应该很清楚了,最后的是 `/5` 是为了拿到0 1 2 3这个值
let newArr = new Array(this.descriptionsList.length);
for(let i = 0; i < this.descriptionsList.length; i++) {
    let newIndex = (i % 5) * 4 + Math.floor(i / 5);
    newArr[newIndex] = this.descriptionsList[i];  // 新索引位置
}
console.log(newArr); // 最终要渲染的数组

还有一种较为直观一点的方式就是直接写对应索引和对应元素,因为我们一开始的时候就一列列出了他要改变的顺序

// 原数组
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
// 变更数组
[0, 4, 8, 12, 16, 1, 5, 9, 13, 17, 2, 6, 10, 14, 18, 3, 7, 15, 17, 19];
let newArr = new Array(this.descriptionsList.length);
newArr[0] = this.descriptionsList[0];
newArr[1] = this.descriptionsList[4];
newArr[2] = this.descriptionsList[8];
newArr[3] = this.descriptionsList[12];
...

这种方式较为直观,只是代码的篇幅稍微长了一丢丢,问题不算太大,大家根据自己实际的情况去书写即可。

🐱 写到最后

  • 今天的分享就到此为止啦!😉
  • 如果大家还有不懂的地方可以在评论区留言或者大家一起讨论哦!
  • 如果这篇文章有帮到您的的话不妨 关注 点赞 收藏 评论 转发支持一下,大家的支持就是我更新最大的动力啦~😆
  • 如果想跟我一起讨论和学习的话,可以私信留言,或者评论区留言,拉你进我的前端学习群哦!
  • 感谢大家支持🤩