0

I'm working with a huge Array of data, for this question I will write something similar avoiding all the key / value.

There is an Array of Objects:

[
  { id: 0, name: 'Tom', age: '18' },
  { id: 1, name: 'Rob', age: '22' },
  { id: 2, name: 'Carl', age: '19' },
  ...
]

Sometimes the user is added or updated and via SSE and I receive back a response of that user object.

What I need is to check if the user is already in the array checking by id. Because if the user has been added I need to do a few actions but if it is just updated I need to do a few others...

Basically what I need is something like: if user.id is in array.user do something, else do something else...

What I tried so far is a for loop, but I don't think it is a good idea, or maybe I used it badly.

Ayeye Brazo
  • 3,316
  • 7
  • 34
  • 67
  • It depends. What is your usage pattern? Do you read a lot more than you modify the array? How big is the list? You could always create an object hash of ids to improve lookup time. – Evan Trimboli Jul 16 '15 at 11:59
  • Are you using simple javascript or a framework such as jQuery or AngularJS? – POZ Jul 16 '15 at 11:59
  • The list is very big, I'm using both jQuery and AngularJS. – Ayeye Brazo Jul 16 '15 at 12:00

6 Answers6

1

Using Array.prototype.filter

You can use Array.prototype.filter, as mentioned in this other question.

var people = [
  { id: 0, name: 'Tom', age: '18' },
  { id: 1, name: 'Rob', age: '22' },
  { id: 2, name: 'Carl', age: '19' }
];

function personExists(id){
  return !!people.filter(function(person){
    return person.id == id;
  }).length;
}

document.body.innerHTML = personExists(2) // true
                        + '<br>'
                        + personExists(5); // false

But that method would loop through all items, even if the person is found from the start.

Using a loop

To avoid this, you could use a good old loop:

var people = [
  { id: 0, name: 'Tom', age: '18' },
  { id: 1, name: 'Rob', age: '22' },
  { id: 2, name: 'Carl', age: '19' }
];

function personExists(id){
  for(var i=0; i<people.length; i++){
      if(people[i].id == id) return true;
  }
  return false;
}

document.body.innerHTML = personExists(2) // true
                        + '<br>'
                        + personExists(5); // false

Using Object property names as IDs

Another method would enhance performance, but would require you to change your Array into an object:

var people = {
  '0' : { name: 'Tom', age: '18' },
  '1' : { name: 'Rob', age: '22' },
  '2' : { name: 'Carl', age: '19' }
};

function personExists(id){
  return people.hasOwnProperty(id);
}

document.body.innerHTML = personExists(2) // true
                        + '<br>'
                        + personExists(5); // false
Community
  • 1
  • 1
blex
  • 24,941
  • 5
  • 39
  • 72
1

To test if a given id is in the array, you can use Array.prototype.some:

var haystack = {/* your object array */},
    // the id to search for:
    needle = 0,

// Array.prototype.some() returns a Boolean true/false
// which corresponds to:
//     true -  one of the object ids is equal to the needle,
//     false - none of the object ids are equal to the needle
idIsInArray = haystack.some(function (obj) {
    return obj.id === needle;
});

var haystack = [{
    id: 0,
    name: 'Tom',
    age: '18'
}, {
    id: 1,
    name: 'Rob',
    age: '22'
}, {
    id: 2,
    name: 'Carl',
    age: '19'
}],
    needle = 0,
    idIsInArray = haystack.some(function (obj) {
        return obj.id === needle;
    });

console.log(idIsInArray);

More usefully, though, would be retrieving the index of the object:

var haystack = [/* your array of objects */],
    needle = 2,

    // Array.prototype.map() retains returns a new array,
    // in this case if the obj.index is equal to the needle
    // it will contain the index of that object, all other
    // values will be undefined:
    needleOnly = haystack.map(function (obj, index) {
        if (obj.id === needle) {
            return index;
        }
    }),

// here we get the index of the needle from the needleOnly array
// we created, which has the same number of elements as the
// haystack array, but contains only the index points of those
// array-elements whose id was equal to the needle:
    needleAtIndex = needleOnly.indexOf(needle);

console.log(needleAtIndex, haystack[needleAtIndex]);

var haystack = [{
    id: 0,
    name: 'Tom',
    age: '18'
  }, {
    id: 1,
    name: 'Rob',
    age: '22'
  }, {
    id: 2,
    name: 'Carl',
    age: '19'
  }],
  needle = 2,
  needleOnly = haystack.map(function(obj, index) {
    if (obj.id === needle) {
      return index;
    }
  }),
  needleAtIndex = needleOnly.indexOf(needle);

console.log(needleAtIndex, haystack[needleAtIndex]);

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
0

If you don't want to use a for loop and aren't stuck with supporting old browsers (e.g. IE8), you could use Array.prototype.filter to return an array with any users that match the userId you're searching for, e.g.

users.filter(function(user) {
    return user.id === userId; 
});

Then you can test whether or not the returned array is empty.

heldinz
  • 78
  • 7
0

You could use the lodash library, the include method.

You could also use the grep method :

 var new_array = $.grep(old_array, function(e) {
        return e.id == id_of_wanted_object;
    });

if the object is present will have length bigger than zero

cs04iz1
  • 1,737
  • 1
  • 17
  • 30
0

If the id is auto generated and not far-off numbers then I would prefer to make array index and id as same. For example,

Object having id as 8 should be on index 8 in the array. Object having id as 10 should be on index 10 in the array.

Hence Object can be picked up by id using the index. But if there are gaps between the ids then this solution will backfire with space complexity.

0
let found = arr.some(key => key.id === key.id);
if (!found) console.log('not found')
Deeksha Sharma
  • 3,199
  • 1
  • 19
  • 16