If I have the following array of objects:

[ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 2, username: 'ted' } ]

Is there a way to loop through the array to check whether a particular username value already exists and if it does do nothing, but if it doesn't to add a new object to the array with said username (and new ID)?

Thanks!

  • 1
    Are Bill and Ted supposed to have the same ID? – user2357112 Apr 3 '14 at 17:18
  • Why there's two elements with the same id? Is that possible that elements will be removed from this array, or can we be sure that the new element will always have id equal to arr.length + 1? – raina77ow Apr 3 '14 at 17:18
  • If you don't want to loop through it, check this Q&A for extending array prototype, stackoverflow.com/questions/1988349/…. – Cem Özer Apr 3 '14 at 17:19
  • native functions are slower compared to normal loops and their support is limited to some browser versions. check my answer below. – Zaheen Nov 10 '17 at 9:21
  • this is a fundamentally wrong question because you can do that by avoiding the use of Arrays. – Bekim Bacaj Nov 10 '17 at 9:28
up vote 112 down vote accepted

I've assumed that ids are meant to be unique here. some is a great function for checking the existence of things in arrays:

function checkAndAdd(name) {
  var id = arr.length + 1;
  var found = arr.some(function (el) {
    return el.username === name;
  });
  if (!found) { arr.push({ id: id, username: name }); }
}

Fiddle

  • 1
    Thanks Andy this is a very clean solution to the problem and is working very well. I had not come across the some method before. Your assumption was correct my ID example was just a typo, I was using arr.length + 1 to determine the ID. – user2576960 Apr 4 '14 at 8:19
  • 3
    Beware that IE8 and earlier do not support the some function. – BetaRide Oct 13 '14 at 6:50
  • Can the found function be made into an IF? Something like: if (arr.some(function (el) { el.Id == someId) and it will return either true or false if it exists or not? – stibay Sep 24 '15 at 17:18
  • @stibay, some does return a boolean. found will either be true or false depending on whether the condition in the callback is met. – Andy Sep 24 '15 at 17:21
  • 1
    Oh, sure: if (arr.some(function (el) { return el.Id == someId; })) { // do something }. Don't forget that return or you won't get anything back. – Andy Sep 24 '15 at 17:26

Accepted answer can also be written in following way using arrow function on .some

 function checkAndAdd(name) {
     var id = arr.length + 1;
     var found = arr.some((el) => {
           return el.username === name;
     });
     if (!found) { arr.push({ id: id, username: name }); }
 }

This small snippets works for me..

const arrayOfObject = [{ id: 1, name: 'john' }, {id: 2, name: 'max'}];

const checkUsername = obj => obj.name === 'max';

console.log(arrayOfObject.some(checkUsername))

Native functions of array are sometimes 3X - 5X times slower than normal loops. Plus native functions wont work in all the browsers so there is a compatibility issues.

My Code:

<script>
  var obj = [];

  function checkName(name) {
    // declarations
    var flag = 0;
    var len = obj.length;   
    var i = 0;
    var id = 1;

    // looping array
    for (i; i < len; i++) {
        // if name matches
        if (name == obj[i]['username']) {
            flag = 1;
            break;
        } else {
            // increment the id by 1
            id = id + 1;
        }
    }

    // if flag = 1 then name exits else push in array
    if (flag == 0) {
      // new entry push in array        
      obj.push({'id':id, 'username': name});
    }
  }
  // function end

  checkName('abc');
</script>

This way you can achieve result faster.

Note: I have not checked if parameter passed is empty or not, if you want you can put a check on it or write a regular expression for particular validation.

The Best Practice is like this.

var arr = ["a","b","c","d"];
console.log(arr.includes("a")); //---- true;
console.log(arr.includes("k")); //---- false;
console.log(arr.includes("c")); //---- true;
  • The question is about array of objects and this won't work. – Adrian Enriquez Oct 17 at 16:07

I think that, this is the shortest way of addressing this problem. Here I have used ES6 arrow function with .filter to check the existence of newly adding username.

var arr = [{
    id: 1,
    username: 'fred'
}, {
    id: 2,
    username: 'bill'
}, {
    id: 3,
    username: 'ted'
}];

function add(name) {
    var id = arr.length + 1;        
            if (arr.filter(item=> item.username == name).length == 0){
            arr.push({ id: id, username: name });
        }
}

add('ted');
console.log(arr);

Link to Fiddle

You could prototype your array to make it more modular, try something like this

    Array.prototype.hasElement = function(element) {
        var i;
        for (i = 0; i < this.length; i++) {
            if (this[i] === element) {
                return i; //Returns element position, so it exists
            }
        }

        return -1; //The element isn't in your array
    };

And you can use it as:

 yourArray.hasElement(yourArrayElement)

I like Andy's answer, but the id isn't going to necessarily be unique, so here's what I came up with to create a unique ID also. Can be checked at jsfiddle too. Please note that arr.length + 1 may very well not guarantee a unique ID if anything had been removed previously.

var array = [ { id: 1, username: 'fred' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' } ];
var usedname = 'bill';
var newname = 'sam';

// don't add used name
console.log('before usedname: ' + JSON.stringify(array));
tryAdd(usedname, array);
console.log('before newname: ' + JSON.stringify(array));
tryAdd(newname, array);
console.log('after newname: ' + JSON.stringify(array));

function tryAdd(name, array) {
    var found = false;
    var i = 0;
    var maxId = 1;
    for (i in array) {
        // Check max id
        if (maxId <= array[i].id)
            maxId = array[i].id + 1;

        // Don't need to add if we find it
        if (array[i].username === name)
            found = true;
    }

    if (!found)
        array[++i] = { id: maxId, username: name };
}
  • I like the simplicity in the other answers, I just posted mine to add the check for unique ID – Uxonith Apr 3 '14 at 17:28
  • Thanks for your answer Uxonith. At the moment I do not have a need for unique ID because I won't be removing users from the array. I will keep this resolution in my back pocket in case the need arises. Thanks again – user2576960 Apr 4 '14 at 8:40

It's rather trivial to check for existing username:

var arr = [{ id: 1, username: 'fred' }, 
  { id: 2, username: 'bill'}, 
  { id: 3, username: 'ted' }];

function userExists(username) {
  return arr.some(function(el) {
    return el.username === username;
  }); 
}

console.log(userExists('fred')); // true
console.log(userExists('bred')); // false

But it's not so obvious what to do when you have to add a new user to this array. The easiest way out - just pushing a new element with id equal to array.length + 1:

function addUser(username) {
  if (userExists(username)) {
    return false; 
  }
  arr.push({ id: arr.length + 1, username: username });
  return true;
}

addUser('fred'); // false
addUser('bred'); // true, user `bred` added

It will guarantee the IDs uniqueness, but will make this array look a bit strange if some elements will be taken off its end.

  • Thanks for this. I went with Andy's solution in the end because it's a more succinct way of achieving the same thing. I won't be removing users at any point so IDs should remain consistent. The check allows users to log in, out and back in again without the array growing overtime. Just for info I'm using this function in conjunction with passport.js and I haven't been able to find a way of removing users from the array without playing with passport code itself. This solution works nicely. – user2576960 Apr 4 '14 at 8:28

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.