2

I had to achieve a quite specific task and as far as I checked I didn't find existing solutions in there so I'm gonna share my work if it helps (I really hope I'm not issuing a duplicate, I found this question Shift array to right by adding a new element to left using js which is not really my goal)

I had to insert an element in an array at a given position, and shift the rest to keep the same order and length. For example:

let array = ['a', 'b', 'd', 'e', 'f'];
const idx = 2;
const new = 'c';

Then the expected output is ['a', 'b', 'c', 'd', 'e']

The question is now: how to proceed, without creating copies and explicitly looping the whole input array ?

3 Answers 3

3

You could splice the array and adjust the length.

const
    array = ['a', 'b', 'd', 'e', 'f'],
    index = 2,
    value = 'c';

array.splice(index, 0, value);
array.length--;

console.log(array);

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

6 Comments

Let's say I'm inserting many instead of one, will the n elements located after the new end of the array be kept in memory for some time ?
@marting, at some time, yes.
Then this solution is potentially consuming a lot of memory for nothing, right ? I am not storing strings but quite heavy objects actually :/
objects are references to storage. there is no heavy data.
@marting: That's an interesting question. The spec says no, they must be deleted. If the array is the only reference, those the elements that had been at these indices are eligible for GC. 262.ecma-international.org/14.0/#sec-arraysetlength. A simple example would be const arr = ['a', 'b', 'c', 'd', 'e']; arr.length = 3; console.log(arr); arr.length = 5; console.log(arr); In the second output line the last two indices are undefined.
|
2

As an alternative to Array::splice() you can use Array::copyWithin():

const
    array = ['a', 'b', 'd', 'e', 'f'],
    index = 2,
    value = 'c';

array.copyWithin(index + 1, index);
array[index] = value;

console.log(array);

2 Comments

looks like an old answer of mine without additional space ...
@NinaScholz didn't see your answer. recently me and another guy wrote exactly the same answer about 15 lines of code, i'd posted like 30 seconds earlier, he deleted his answer)
0

So, I came up with this solution ─ don't hesitate to tell if there's a better way to do this !

let array = ['a', 'b', 'd', 'e', 'f'];
const idx = 2;
const new = 'c';

array.splice(idx, array.length-idx, new).forEach((e, i, a) => {
  if (i < a.length-1) {
    array.push(e);
  }
});

splice returns an array with the removed elements: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

forEach takes (element, index, array upon which forEach is called) as parameters: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

7 Comments

Just insert your element and then push the rest without the last element
That is what I'm doing, or could you be more precise ?
This forEach is not necessary, you can just push all the items at once
You mean something like array.push(...splicedArray) ? Still need to remove last element beforehand
Yeah, that's exactly what I said in first comment - insert your element and then push the rest without the last element
|

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.