1

I have an array that contains all ids and an array that holds all valid ids.
I just want to retrieve the invalid ids.

It could obviously be done by for loops, but if possible I'd like to do it using the .filter() method to keep it short and maybe more transparent.

The problem is that the array containing the valid ids looks a lot different fron the array that contains all ids. Let me show you:

var allIds = ["1673","2456","8977","5467"];
var validIds = [ {_id: "2456"}, {_id: "5467"} ];

var invalidIds = []; //as non-associative array

invalidIds = allIds.filter(function(x) { return validIds[x]["_id"].indexOf(x) < 0 });

console.log(invalidIds); //Uncaught TypeError: Cannot read property '_id' of undefined

Is there a way to fix that?

2
  • x is already the object with the _id. And why indexOf? You are comparing two numbers at that point, you can use value equality ===. Commented Aug 28, 2015 at 8:33
  • Oh, I forgot to mention that my ids actually are strings. ...I edited that real quick. Commented Aug 28, 2015 at 8:35

2 Answers 2

3

If you really insist on not using for-loops, you could, but it would be better to, since it would allow you to short-circuit the checking once you find a match.

var allIds = ["1673","2456","8977","5467"];
var validIds = [ {_id: "2456"}, {_id: "5467"} ];
var invalidIds = allIds.filter(function (id) {
  return !validIds.reduce(function (contains, item) {
    return contains || (item._id === id);
  }, false);
}); //["1673", "8977"]
Sign up to request clarification or add additional context in comments.

4 Comments

Interesting, there seems to be almost no difference in execution time between yours and Andreas answer. jsfiddle.net/zgeL59jr
@Forivin Why would you expect there to be one? The code is nearly identical.
Well, but they use different methods and we are talking a million iterations. I would have expected some sort of winner here. But it was pretty much random which one was faster. I mean doing a for loop on an array and doing a forEach an an array can look pretty similar too, but I doubt that they would perform the same.
@Forivin Both some and reduce are array prototype methods and their respective specs (see Array.prototype.some and Array.prototype.reduce) are nearly identical. Since the operations they perform are very similar, their implementations are also nearly the same.
2

Array.prototype.filter + Array.prototype.some

var allIds = ["1673", "2456", "8977", "5467"];
var validIds = [{_id: "2456"}, {_id: "5467"}];

var invalidIds = allIds.filter(function (id) {
    return !validIds.some(function (validId) {
        return validId._id === id;
    });
});

console.log(invalidIds); // ["1673", "8977"])

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.