1

I am dealing with a fairly complex object. It contains 2 arrays, which contain 3 arrays each of objects:

enter image description here

I'm trying to delete one of the history: Array[2] if one of the objects in it has username: null.

var resultsArray = result.history;
var arrayCounter = 0;

resultsArray.forEach(function(item) {
    item.forEach(function(innerItem) {
        if (innerItem.username == null) {
            resultsArray.splice(arrayCounter,1);
        };
    });
    arrayCounter++;
});

Looking through answers it's recommended to do something like:

resultsArray.splice(arrayCounter,1);

This isn't working in this situation because more than one of the objects could have username == null and in that case it will delete multiple history objects, not just the one that I want.

How do I remove only the one specific history array index if username == null?

3
  • What's stopping you from just iterating through resultsArray and it's child arrays with regular for(;;) syntax, and then breaking out of the loops when the first match has been encountered and dealt with? Commented Dec 22, 2015 at 22:02
  • Breaking in the inner array after the 1st match would stop the whole thing and not evaluate the 2nd (in this case) history: Array[2]. Right? Commented Dec 22, 2015 at 22:04
  • 1
    All possible options described in this question: stackoverflow.com/questions/6260756/… Commented Dec 22, 2015 at 22:15

5 Answers 5

1

splice is evil. I think using immutable array methods like filter might be easier to reason about:

x.history =
  x.history.filter(function (h) {
    return !h.some(function (item) {
      return item.username === null
    })
  })

Go through all the histories, and do not include them in the filter if they have a username that is null.

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

Comments

1

My understanding was that you only want to delete the first outer array that has an inner array that has an object with a null username. Heres one solution closest to your current form:

var resultsArray = result.history;
var arrayCounter = 0;
var foundFirstMatch = false;

resultsArray.forEach(function(item) {
    if (!foundFirstMatch) {
        item.forEach(function(innerItem) {
            if (innerItem.username == null && !foundFirstMatch) {
                foundFirstMatch = true;
            };
        });
        arrayCounter++;        
     }
});


if (foundFirstMatch > 0)
    resultsArray.splice(arrayCounter, 1);

Other syntax:

var resultsArray = result.history;
var outerNdx;
var innerNdx;
var foundMatch = false;

for (outerNdx = 0; !foundMatch && outerNdx < resultsArray.length; outerNdx++) {
   for (innerNdx = 0; !foundMatch && innerNdx < resultsArray[outerNdx].length; innerNdx++) {
      if (resultsArray[outerNdx][innerNdx].username == null) {
         foundMatch = true;
      }
    }
 }

 if (foundMatch)
    resultsArray.splice(outerNdx, 1);

2 Comments

It's the occurrence of the outer item if one of the inner has a null username.
Yeah, I misspoke, sorry. I think these are potential solutions.
1

Update - here's how I'd do it now, without lodash:

thing.history.forEach((arr, i) => {
  thing.history[i] = arr.filter( (x) => x.username !== null );
});

Previous answer:

I'd use lodash like this:

_.each(thing.history, function(array, k){
  thing.history[k] = _.filter(array, function(v){
    return v.username !== null;
  })
});

Here's a jsfiddle:

https://jsfiddle.net/mckinleymedia/n4sjjkwn/2/

Comments

0

You should write something like this:

var resultsArray = result.history.filter(function(item){
    return !item.some(function(inner){ return inner.username==null; });
});

Comments

0

The foreach loop cant break in this way but a regular for loop can. This is working:

result.history.forEach(function(item) {
    loop2:
    for (var i = 0; i < item.length; i++) {
        var innerItem = item[i];
        console.log(innerItem);
        break loop2;
    }
});

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.