Splice an array in half, no matter the size?

JavascriptArrays

Javascript Problem Overview


I have an array I would like to split in half. So I can position the first half on the right side and the second half on the left side.

I have used the splice function before:

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

But not sure how to splice it in half no matter the size, because the array will change in size dynamically.

Javascript Solutions


Solution 1 - Javascript

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

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

edited the code following @Lightness Races in Orbit and @pubkey comments.

Solution 2 - Javascript

Avoid Mutations

If you need to avoid mutations, for example if you have to split an array in react you don't want to mutate the original or it could lead to some very strange behaviour in your app.

What is a Mutation?

A mutation is when you change a non primitive, like an object or array. Using an array method like splice will cause the original array to be manipulated. You can always tell if a method will mutate by whether or not it returns a new array or object.

Why can Mutations be "bad"?

When you mutate an object or array you change that original reference. This means that if you use the original reference you will get the new value. This is best shown with an example.

const myObj = { key: "some value" };
const newObj = myObj;
newObj.key = "some other value";
console.log(myObj) // will log { key: "some other value" };

As you can see the object myObj had the value of key changed as well. Scary stuff.

Use Slice

You can get around this by using slice instead of splice

Example

let yourArray = props.someArray;
let halfwayThrough = Math.floor(yourArray.length / 2)
// or instead of floor you can use ceil depending on what side gets the extra data

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

Solution 3 - Javascript

You can simply refer to the array's length:

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

Since .splice() actually removes elements from the source array, the remaining elements in the array will be the elements for the right half.

Math.floor() will round down to give the left side one less than the right side for odd lengths. You could use Math.ceil() if you want to round up to give the left side one more than the right side when the length is odd.

Solution 4 - Javascript

Take a look at lodash chunk:

var myArray = [1, 2, 3, 4, 5, 6, 7, 8];
var pivot = _.ceil(myArray.length / 2);
// => 4
console.log(_.chunk(myArray, pivot));

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Solution 5 - Javascript

You can use ES6 destructing also and slice() so that the original array isn't mutated.

   const yourArray;
   let leftSide,rightSide;
   const m = Math.floor(yourArray.length/2);
   const [leftSide,rightSide] = [yourArray.slice(0,m), yourArray.slice(m,yourArray.length)];
   console.log(leftSide);
   console.log(rightSide);

Solution 6 - Javascript

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

For example:

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']

More information: splice in the MDN docs


Note that this modifies your original array. If you want to keep the original array, clone the array, then use splice on the cloned array. From an SO question about cloning arrays: > 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.

//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];

Solution 7 - Javascript

This is a fun function for Avoiding Mutations with options:

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;
  }, [[], []]);
}

And you can call it with an alternating option:

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);

Solution 8 - Javascript

if you want the size of the array to stay equal you just need to alternate which array you write to (eg, alternate .push calls on the arrays).. Why don't you just create 2 arrays up front?

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

After you do that if you want to keep the 2 arrays the same size alternate between

leftHalf.push(newElement);

and

yourArray.push(newElement1);

Solution 9 - Javascript

Another alternative, you probably shouldn't use it though.

[1,2,3,4,5,6,7,8,9,10].reduce(([l, r], cur, i, self) => i < self.length / 2 ? [[...l, cur], r] : [l, [...r, cur]], [[], []])

Solution 10 - Javascript

you can use filter as another available way to solve it.

let arr = [1,2,3,4,5,6];
let half = arr.filter((el, i) => i >= arr.length/2);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionXtianView Question on Stackoverflow
Solution 1 - Javascriptredmoon7777View Answer on Stackoverflow
Solution 2 - JavascriptJoe LloydView Answer on Stackoverflow
Solution 3 - Javascriptjfriend00View Answer on Stackoverflow
Solution 4 - JavascriptPenny LiuView Answer on Stackoverflow
Solution 5 - JavascriptPradeep MauryaView Answer on Stackoverflow
Solution 6 - JavascriptNonameSLView Answer on Stackoverflow
Solution 7 - JavascriptparkerView Answer on Stackoverflow
Solution 8 - JavascriptMatt WolfeView Answer on Stackoverflow
Solution 9 - JavascriptTeiemView Answer on Stackoverflow
Solution 10 - JavascriptalehaView Answer on Stackoverflow