Jhon
Jhon

Reputation: 145

array.split("stop here") array to array of arrays in javascript

So the goal is to fragment an array to subarrays on the stumble of a certain element Example below for array.split("stop here")

["haii", "keep", "these in the same array but", "stop here", "then continue", "until you reach", "another", "stop here", "and finally", "stop here", "stop here"]

that to

[
  ["haii", "keep", "these in the same array but"], ["then continue", "until you reach", "another"], ["and finally"]
]

What I tried till now is not working very well:

Array.prototype.split = function (element) {
  const arrays = [];
  // const length = this.length;
  let arrayWorkingOn = this;
  for(let i=0; i<arrayWorkingOn.length; i++) {
    if(this[i] === element) {
      const left = arrayWorkingOn.slice(0, i);
      const right = arrayWorkingOn.slice(i, arrayWorkingOn.length);
      arrayWorkingOn = right;
      arrays.push(left);
      console.log(right);
    }
  }
  arrays.push(arrayWorkingOn); //which is the last 'right'
  return arrays;
}

Thanks in advance for your time and effort!

Upvotes: 3

Views: 171

Answers (4)

ibrahim mahrir
ibrahim mahrir

Reputation: 31692

If you're going to loop the entire array then don't use slice at all, just accumulate the items as you go in an array and when you encounter the element just push that array and create a new one, like so:

Array.prototype.split = function (element) {
  const arrays = [];

  let currentArray = [];                         // is used to accumulate the sub arrays
  for(let item of this) {                        // for each item of the array
    if(item === element) {                       // if item is the element
      arrays.push(currentArray);                 // add the current accumulated array to arrays
      currentArray = [];                         // and start accumulating a new one
    } else {                                     // otherwise
      currentArray.push(item);                   // add the item to the accumulated array
    }
  }
  arrays.push(currentArray);                     // don't forget the last one

  return arrays;
}

Note: This answer uses the correct behavior of split which is not what the question asks. There should be empty arrays in the resulting array if the elements you want to split on are the first item, the last item or adjacent items in the original array. 'abcbdb'.split('b') should result in ['a', 'c', 'd', ''] not ['a', 'c', 'd']. If you want to ignore the empty arrays, check out Jhon's accepted answer above.

Demo:

Array.prototype.split = function (element) {
  const arrays = [];

  let currentArray = [];
  for(let item of this) {
    if(item === element) {
      arrays.push(currentArray);
      currentArray = [];
    } else {
      currentArray.push(item);
    }
  }
  arrays.push(currentArray);

  return arrays;
}


let result = ["haii", "keep", "these in the same array but", "stop here", "then continue", "until you reach", "another", "stop here", "and finally", "stop here", "stop here"].split("stop here");

console.log(result);

Upvotes: 1

Jhon
Jhon

Reputation: 145

This answer is inspired by the answer of ibrahim mahrir.

Array.prototype.split = function (element) {
  const arrays = [];
  const length = this.length;
  let accumulatedArray = [];
  for(let i=0; i<length; i++) {
    if( this[i] === element ) {
      if( accumulatedArray.length > 0 ) arrays.push(accumulatedArray);
      accumulatedArray = [];
    } else {
      accumulatedArray.push(this[i]);
    }
  }
  if( accumulatedArray.length > 0 ) arrays.push(accumulatedArray);;
  return arrays;
}

Upvotes: 1

Ilijanovic
Ilijanovic

Reputation: 14904

First .join() your arrays with an unique seperator in my case UNIQUE_SEPERATOR

Then you split it up first with .split("stop here") that returns you an array with 3 strings in it.

Now you need to .map() over the array and split it up by your seperator (UNIQUE_SEPERATOR) and .filter() out the "" values.

At the end you filter out the empty arrays by checking its length and you are done.

let arr = [
  "haii",
  "keep",
  "these in the same array but",
  "stop here",
  "then continue",
  "until you reach",
  "another",
  "stop here",
  "and finally",
  "stop here",
  "stop here"
];

Array.prototype.split = function() {
  return this.join("UNIQUE_SEPERATOR")
    .split("stop here")
    .map(el => el.split("UNIQUE_SEPERATOR").filter(Boolean))
    .filter(arr => arr.length);
};

console.log(arr.split());

Upvotes: 1

Mathieu K.
Mathieu K.

Reputation: 933

A few thoughts:

  1. Rewritting prototypes is an advanced idea, and probably unecessary.

  2. Look into utility librairies such as lodash for utility functions such as this one.

  3. If you want to do it manually anyway, I'd try:

    array.join("/$/").split("stop here").map(part => part.split("/$/").filter(Boolean))

That first convert your array to a string that has a split methods and back to an array again.

Demo:

const array = ["haii", "keep", "these in the same array but", "stop here", "then continue", "until you reach", "another", "stop here", "and finally", "stop here", "stop here"]
console.log(array.join("/$/").split("stop here").map(part => part.split("/$/").filter(Boolean)))

Upvotes: 0

Related Questions