1

There is sourceArray and some additionalArray. Need to add items from additionalArray to the end of sourceArray. And in result sourceArray contains all items (no create new array). The problem is items count of additionalArray may be thousands.

// example
push([], [1, 2, 3], [10, 20, 30]) // [1, 2, 3, 10, 20, 30]
push(['a', 'b'], 'x', ['z', '0']) // ['a', 'b', 'x', 'z', '0']
// my solution
function push(sourceArray, ...additionalArray) {
    additionalArray.forEach((array) => {
        array = Array.isArray(array) ? array : [array];
        if (array.length < 1000) {
            sourceArray.push.apply(sourceArray, array);
        } else {
            array.forEach((item) => sourceArray.push(item));
        }
    });
    return sourceArray;
}

My question is there more elegant solution for this task?

5
  • Why don't you use the spread operator? const newArray = [...sourceArray, ...additionalArray] Commented Apr 11, 2022 at 13:06
  • @SajeebAhamed Because I heard about limit of count items Commented Apr 11, 2022 at 13:10
  • If you need the original array reference to be unmodified (i.e. no new array) then you can split up your array params into groups before iterating them and pushing into the original array. Basically what's been suggested but using groups to ensure you don't max out the push params limit. Commented Apr 11, 2022 at 13:11
  • Since you're not creating a new array, is there really any sense in returning sourceArray? It's passed by reference and updated. Commented Apr 11, 2022 at 14:10
  • @PeterKA sometimes is more convenient. For example, with one line =>. Commented Apr 11, 2022 at 16:28

2 Answers 2

1

You might find using .flat() can help you here. If you use that on additionalArray, you can then spread ... those elements into a call to .push() as arguments:

const push = (source, ...rest) => {
  source.push(...rest.flat());
  return source;
}

console.log(push([], [1, 2, 3], [10, 20, 30])) // [1, 2, 3, 10, 20, 30]
console.log(push(['a', 'b'], 'x', ['z', '0'])) // ['a', 'b', 'x', 'z', '0']

This does have a limitation though in that .push() can only accept a certain amount of arguments. You might hit the max argument limit and this can throw considering that your additionalArray can be large. Using a for..of loop would help with that:

const push = (source, ...rest) => {
  for(const item of rest.flat())
    source.push(item)
  return source;
}

console.log(push([], [1, 2, 3], [10, 20, 30])) // [1, 2, 3, 10, 20, 30]
console.log(push(['a', 'b'], 'x', ['z', '0'])) // ['a', 'b', 'x', 'z', '0']

Sign up to request clarification or add additional context in comments.

2 Comments

No need of returning source.
@PeterKA yes there isn't a need, but usually, these types of methods return the target (which op has named the source for some reason) for convenience (otherwise my console.logs above wouldn't work), take Object.assign() for example or .sort(). So just following that behavior. If OP wants something else returned (like the length), then they can do that also
0

As of MDN, you can use the array spread syntax:

let vegetables = ['parsnip', 'potato']
let moreVegs = ['celery', 'beetroot']

// Merge the second array into the first one
vegetables.push(...moreVegs);

console.log(vegetables)  // ['parsnip', 'potato', 'celery', 'beetroot']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.