Say I have an array var arr = [1, 2, 3]
, and I want to separate each element by an element eg. var sep = \"&\"
, so the output is [1, \"&a
You could use Array.from
to create an array with the final size, and then use the callback argument to actually populate it:
const intersperse = (arr, sep) => Array.from(
{ length: Math.max(0, arr.length * 2 - 1) },
(_, i) => i % 2 ? sep : arr[i >> 1]
);
// Demo:
let res = intersperse([1, 2, 3], "&");
console.log(res);
if (!Array.prototype.intersperse) {
Object.defineProperty(Array.prototype, 'intersperse', {
value: function(something) {
if (this === null) {
throw new TypeError( 'Array.prototype.intersperse ' +
'called on null or undefined' );
}
var isFunc = (typeof something == 'function')
return this.concat.apply([],
this.map(function(e,i) {
return i ? [isFunc ? something(this[i-1]) : something, e] : [e] }.bind(this)))
}
});
}
A spread and explicit return in reducing function will make it more terse:
const intersperse = (arr, sep) => arr.reduce((a,v)=>[...a,v,sep],[]).slice(0,-1)
// intersperse([1,2,3], 'z')
// [1, "z", 2, "z", 3]
export const intersperse = (array, insertSeparator) => {
if (!isArray(array)) {
throw new Error(`Wrong argument in intersperse function, expected array, got ${typeof array}`);
}
if (!isFunction(insertSeparator)) {
throw new Error(`Wrong argument in intersperse function, expected function, got ${typeof insertSeparator}`);
}
return flatMap(
array,
(item, index) => index > 0 ? [insertSeparator(item, index), item] : [item] // eslint-disable-line no-confusing-arrow
);
};
javascript has a method join() and split()
var arr = ['a','b','c','d'];
arr = arr.join('&');
document.writeln(arr);
Output should be: a&b&c&d
now split again:
arr = arr.split("");
arr is now:
arr = ['a','&','b','&','c','&','d'];
One straightforward approach could be like feeding the reduce function with an initial array in size one less than the double of our original array, filled with the character to be used for interspersing. Then mapping the elements of the original array at index i to 2*i in the initially fed target array would do the job perfectly..
In this approach i don't see (m)any redundant operations. Also since we are not modifying any of the array sizes after they are set, i wouldn't expect any background tasks to run for memory reallocation, optimization etc. One other good part is using the standard array methods since they check all kinds of mismatch and whatnot.
This function returns a new array, in which the called upon array's items are interspersed with the provided argument.
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
Array.prototype.intersperse = function(s){
return this.reduce((p,c,i) => (p[2*i]=c,p), new Array(2*this.length-1).fill(s));
}
document.write("<pre>" + JSON.stringify(arr.intersperse("&")) + "</pre>");