Reputation: 145
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
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
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
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
Reputation: 933
A few thoughts:
Rewritting prototypes is an advanced idea, and probably unecessary.
Look into utility librairies such as lodash for utility functions such as this one.
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