0

I have an array with various paragraphs inside:

var content = [ "<p>This is a paragraph 1</p>", 
                "<p>This is a paragraph 2</p>", 
                "<p>This is a paragraph 3</p>", 
                "<p>This is a paragraph 4</p>", 
                "<p>This is a paragraph 5</p>" ]

I want to perform a simple operation on each element inside the array. Each paragraph needs to be placed inside a container and then be removed from the array. This is the corresponding HTML:

<div class="article">
  <div id="cell1" class="text-block">
    <div class="container"></div>
  </div>
</div>

And this is how I am attempting to do what I describe above:

for (i = 0; i < content.length; i++) {
  console.log("Current item: " + content[i])
  //
  var itemtoRemove = content[i];
    $("#cell1 .container").append(content[i]);
  //
  content.splice($.inArray(itemtoRemove, content), 1)
}

I have put everything together in a fiddle as well: https://jsfiddle.net/johschmoll/1mjzu4qg/71/

Basically, everything is working fine, but the for-statement seems to be skipping every second element in the array. I cannot figure out the reason, even after looking at similar cases. What am I doing wrong here?

11
  • 2
    If you are going to manipulate the array while looping over it, you need to start at the length - 1 index and move backwards. Because once you remove the first element and your i adjusts to 1, you're effectively looking at originally the 3rd element Commented Jan 3, 2020 at 16:42
  • Array#splice mutates the original array. Could it be that? Commented Jan 3, 2020 at 16:42
  • content.splice modifies the array while you're looping over it. Commented Jan 3, 2020 at 16:42
  • Otherwise, switch away from a for loop and use a while (content.length) loop Commented Jan 3, 2020 at 16:42
  • 1
    Because of the issue you just ran into, :) Commented Jan 3, 2020 at 16:48

2 Answers 2

3

Since you are modifying the array as you loop, use a while loop that checks that the array is not empty

while (content.length) {
  console.log("Current item: " + content[0])
  //
  var itemtoRemove = content[0];
    $("#cell1 .container").append(content[0]);
  //
  content.shift();
}

Keeping in mind that if all you are doing is appending all the elements, then this is unnecessary. append() can accept an array

$("#cell1 .container").append(content.splice(0));
Sign up to request clarification or add additional context in comments.

5 Comments

Regarding your note: Well, I am only appending, but it is important that the appended elements get removed from the array
So, append with the array and then set the array to an empty array. Two operations
I should explain the context in which I'm using this: I'm working on a script that places paragraphs into a container until this container is "full", all paragraphs that do not fit get put into a separate container. That is why I need to modify the array. See here: jsfiddle.net/johschmoll/1mjzu4qg/96 Happy about any and all advice on this.
Ok, so in your example there, you are not simply appending the elements. You are conditionally appending the elements to different things. That's a different use case. The only thing I would say about that snippet is to point out the usage of shift() rather than splice()
Yeah, thanks for pointing it out. shift() was new for me, always a pleasure learning something new.
1

Because you are modifying the array upon each iteration, the length of the array changes and you wind up skipping items. Instead, loop through the array backwards to avoid the issue.

var content = [ "<p>This is a paragraph 1</p>", 
                "<p>This is a paragraph 2</p>", 
                "<p>This is a paragraph 3</p>", 
                "<p>This is a paragraph 4</p>", 
                "<p>This is a paragraph 5</p>" ]

for (var i = content.length-1; i >= 0 ; i--) {
  console.log("Current item: " + content[i])

  var itemtoRemove = content[i];
  $("#cell1 .container").append(content[i]);

  content.splice($.inArray(itemtoRemove, content), 1)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="article">
  <div id="cell1" class="text-block">
    <div class="container"></div>
  </div>
</div>

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.