简体   繁体   中英

Iterating over and comparing properties of two arrays of objects

I have set up a HBS helper which takes in two arrays of objects (users privileges). What I want to do is compare them and inject back into the template the privileges the user does and doesn't have.

Presently I can compare the names of the privileges with the following code:

hbs.registerHelper('selected', function(option, value){
  var i;
  var j;
  var privName;
  var userPriv;

  var privObj = new Object();
  var privArray = [];

  for(i in option){
    console.log('each ' + JSON.stringify(option[i]));
    privName = option[i].privname;

    for (y in value){
      if(privName == value[y].privname){

      userPriv = value[y].privname;
      console.log('user has the following privileges', value[y].privname);

      privObj = new Object();
      privObj.name = userpriv;
      privObj.id = value[y]._id;
      privObj.state = 'selected';
      privArray.push(privObj);

    } else if (privName != value[y].privname){
      console.log('user doesnt have priv ', privName);

      privObj = new Object();
      privObj.name = option[i].privname;
      privObj.id = option[i].id;
      privObj.state = '';
      privArray.push(privObj);

    }

  }
}

console.log('privileges array ', privArray);
return privArray;

}); 

This works OK when the user only has one privilege, however when the user has more than one, for example two privileges, it returns the privileges twice. If the user has 3, thrice and so on. I know this is because the array is looping again because their are 2, 3 etc in the .length. However I can't seem to find an adequate solution.

Any help?

PS it would be nice if the Array.includes() method allowed you to search object properties.

The problem creating new objects the way you did is that for each property you add to your privilege-entity you will have to return to that function and set that property as well. You can instead just add/alter the state property of the existing objects:

hbs.registerHelper('selected', function(option, value) {
    var names = option.map(function(opt) {
        return opt.privname;
    });  
    value.forEach(function(val) {
        val.state = names.indexOf(val.privname) >= 0 ? 'selected' : '';
    });
    return value;
}); 

Basically:

  • The variable names is being mapped to be an array only with the privnames. You can check by using console.log(names) .
  • The Array.forEach() function is helpful in this case because you just need to iterate over each object inside value and set its state -property.
  • To check if the privname exists, you just need to check the index in the previous names -mapped-array. For such a simple thing I used ternary operator ( ?: ).
  • Finally, you return value , which is the array containing the objects you had updated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM