关于javascript:将数组分割成两半,不管大小如何?

Splice an array in half, no matter the size?

我有一个数组要分成两半。所以我可以把前半部分放在右边,下半部分放在左边。

我以前使用过拼接功能:

1
var leftSide = arrayName.splice(0,2);

但不知道如何将它拼接成两半,无论大小如何,因为数组的大小都会动态变化。


1
2
3
var half_length = Math.ceil(arrayName.length / 2);    

var leftSide = arrayName.splice(0,half_length);

编辑了以下代码:@lightness races in orbit comment


避免突变

如果你需要避免突变,例如,如果你必须在React中分割一个数组,你不想改变原始数组,否则它会导致你的应用程序中出现一些非常奇怪的行为。

使用切片

你可以通过使用slice而不是splice来解决这个问题。

例子

1
2
3
4
5
let yourArray = props.someArray;
let halfWayThough = Math.floor(yourArray.length / 2)

let arrayFirstHalf = yourArray.slice(0, halfWayThough);
let arraySecondHalf = yourArray.slice(halfWayThough, yourArray.length);


您可以简单地引用数组的长度:

1
var leftSide = arrayName.splice(0, Math.floor(arrayName.length / 2));

由于.splice()实际上从源数组中删除了元素,所以数组中的其余元素将是右半部分的元素。

对于奇数长度,Math.floor()将向下取整,使左侧比右侧少一个。如果你想在长度为奇数的情况下,使左侧比右侧多出一个,你可以使用Math.ceil()


1
2
let leftSide = myArray.splice(0, Math.ceil(myArray.length / 2));
//The right side is stored in"myArray"

例如:

1
2
3
4
5
6
7
let letters = ['a', 'b', 'c', 'd', 'e'];
let leftSide = letters.splice(0, Math.ceil(letters.length /2));
let rightSide = letters;
console.log(leftSide);
=> ['a', 'b', 'c']
console.log(rightSide);
=> ['d', 'e']

更多信息:MDN文档中的splice

请注意,这将修改原始数组。如果要保留原始数组,请克隆该数组,然后在克隆的数组上使用拼接。从克隆阵列的问题来看:

There has been a huuuge BENCHMARKS thread, providing following information:

  • for blink browsers slice() is the fastest method, concat() is a bit slower, and while loop is 2.4x slower.

  • for other browsers while loop is the fastest method, since those browsers don't have internal optimizations for slice and concat.

1
2
3
4
5
6
//Fastest for Blink browsers (Opera/Chromium):
let clonedArray = originalArray.slice();
//For other browsers:
let clonedArray = [];
var i = myArray.length;
while (i--) clonedArray[i] = myArray[i];

看一看洛达什·埃多克斯(Lodash EDOCX1)(6):

1
2
3
4
var myArray = [1, 2, 3, 4, 5, 6, 7, 8];
var pivot = _.ceil(myArray.length / 2);
// => 4
console.log(_.chunk(myArray, pivot));
1
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js">


这是一个避免选项突变的有趣功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function splitArray({ alternate, array }) {
  const halfIndex = Math.ceil(array.length / 2) - 1;
  let firstArray = true;
  return array.reduce((res, item, index) => {
    if (firstArray) {
      res[0].push(item);
      if (alternate || index >= halfIndex) {
        firstArray = false;
      }
    } else {
      res[1].push(item);
      if (alternate) {
        firstArray = true;
      }
    }
    return res;
  }, [[], []]);
}

你可以用一个交替的选项来称呼它:

1
2
3
4
5
6
7
const myArray = [1,2,3,4,5,6,7,8];
const splitAlternate = splitArray({ alternate: true, array: myArray });
const splitNoAlternate = splitArray({ alternate: false, array: myArray });

console.log(myArray);
console.log(splitAlternate);
console.log(splitNoAlternate);


如果希望数组的大小保持相等,只需交替写入哪个数组(例如,对数组的alternate.push调用)。为什么不在前面创建两个数组呢?

1
var lelftHalf = yourArray.splice(0,arrayName.length / 2);

完成后,如果要保持两个数组的大小相同,请在

1
leftHalf.push(newElement);

1
yourArray.push(newElement1);