-1

I need to push array of elements inside another array at a particular index in javascript without using spread operator and without using another array.

Input:

let firstArray = [4,5,6];
let secondArray = [1,2,3,7,8,9];

Expected Output:

console.log(secondArray); //[1,2,3,4,5,6,7,8,9];

I tried using splice and apply function like below.

let firstArray = [4,5,6];
let secondArray = [1,2,3,7,8,9];
firstArray.splice(0, 0, 3, 0); 
secondArray.splice.apply(secondArray, firstArray);

This code gives expected output but also updating the elements in firstArray before updating the secondArray.

Is there any better way to achieve the expected output without updating the elements in firstArray?

Edit 1: I am trying to achieve this without new array because the size of the firstArray and secondArray are huge. Thus feeling it might create unwanted memory allocation for new array to just push elements into another array. Avoiding spread operator as it is not supported in IE browsers Edit 2: Removed without using loops condition.

Arun Kumar
  • 49
  • 5
  • 3
    *"...without using spread operator or loops and without using another array."* Why not? Those are the obvious ways. The question really doesn't make any sense with just an arbitrary restriction like that. – T.J. Crowder Dec 18 '21 at 11:16
  • Without using loops, spread syntax, How is it possible to get all array values from an array `firstArray` – DecPK Dec 18 '21 at 11:19
  • If the first array is not dynamic then you can do as: `secondArray.splice(3, 0, firstArray[0], firstArray[1], firstArray[2]);` else you have to use some kind of iteration mechnaism – DecPK Dec 18 '21 at 11:22
  • 2
    Your code and [this answer](https://stackoverflow.com/a/7032807/157247) to the duplicate target Andreas linked both get you really close. You just have to add a bit to remove the elements added to `firstArray` via `unshift` (`splice` in your code) when you're done. – T.J. Crowder Dec 18 '21 at 11:25
  • 2
    @T.J.Crowder I somehow ignored the _"without using another array"_ part :/ – Andreas Dec 18 '21 at 11:30
  • @Andreas - Gosh, I've **never** done that when marking a dupe. ;-) – T.J. Crowder Dec 18 '21 at 11:32
  • @T.J.Crowder Thanks for your anwser. I decided to achieve this without new array because the size of the firstArray and secondArray are huge. Thus feeling it might create unwanted memory allocation for new array to just push elements into another array. – Arun Kumar Dec 18 '21 at 11:37
  • 1
    @ArunKumar - Thanks for replying. Please edit the question to say that. – T.J. Crowder Dec 18 '21 at 11:38
  • @ArunKumar - That doesn't explain not using a loop, though. `splice` is a loop, after all. – T.J. Crowder Dec 18 '21 at 11:43
  • @T.J.Crowder Yes, splice is a loop. But avoiding loop in this statement to improve code readability. – Arun Kumar Dec 18 '21 at 11:47
  • @ArunKumar - It doesn't. – T.J. Crowder Dec 18 '21 at 11:51
  • @T.J.Crowder Please suggest any possible solutions to achieve this output without affecting code readability? Even using loops is fine. – Arun Kumar Dec 18 '21 at 11:58

1 Answers1

1

You've said your reason for the constraints is:

...because the size of the firstArray and secondArray are huge. Thus feeling it might create unwanted memory allocation for new array to just push elements into another array.

That being the case, you want to avoid that .splice(0, 0, 3, 0) on firstArray, since it requires moving everything in firstArray over to make room for the elements.

Your memory issue doesn't explain the prohibition on using a loop (after all, splice uses a loop) and copyWithin (also a loop) combined with a loop to fill in the new elements would be a clean, simple, and not memory-intensive way to solve the problem. So:

function insert(target, source, index) {
    // Get the count of elements to copy
    let count = source.length;
    if (count) {
        // 1. First, make room by copying elements out of the way
        let targetIndex = index + source.length;
        target.length += count;
        target.copyWithin(targetIndex, index, index + count);
        // 2. Now, fill in the new elements
        while (count-- > 0) {
            target[targetIndex--] = source[count];
        }
    }
    return target;
}

Live Example:

let firstArray = [4,5,6];
let secondArray = [1,2,3,7,8,9];

function insert(target, source, index) {
    // Get the count of elements to copy
    let count = source.length;
    if (count) {
        // 1. First, make room by copying elements out of the way
        let targetIndex = index + source.length;
        target.length += count;
        target.copyWithin(targetIndex, index, index + count);
        // 2. Now, fill in the new elements
        while (count-- > 0) {
            target[targetIndex--] = source[count];
        }
    }
    return target;
}

insert(secondArray, firstArray, 3);
console.log(JSON.stringify(secondArray)); // [1,2,3,4,5,6,7,8,9];
console.log(JSON.stringify(firstArray));  // [4,5,6];

If the while loop seems a bit opaque to you, you can also write the loop part of that like this:

for (let index = 0; index < count; ++index) {
    target[targetIndex + index] = source[index];
}

Live Example:

let firstArray = [4,5,6];
let secondArray = [1,2,3,7,8,9];

function insert(target, source, index) {
    // Get the count of elements to copy
    let count = source.length;
    if (count) {
        // 1. First, make room by copying elements out of the way
        let targetIndex = index + source.length;
        target.length += count;
        target.copyWithin(targetIndex, index, index + count);
        // 2. Now, fill in the new elements
        for (let index = 0; index < count; ++index) {
            target[targetIndex + index] = source[index];
        }
    }
    return target;
}

insert(secondArray, firstArray, 3);
console.log(JSON.stringify(secondArray)); // [1,2,3,4,5,6,7,8,9];
console.log(JSON.stringify(firstArray));  // [4,5,6];

Note that copyWithin is probably not supported by IE11, but is easily polyfilled.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875