Javascript:如何根据属性通过单义键合并两个数组?

Javascript: how to merge two arrays by univocal key, and based on property?

我有两个数组:一个用于人,一个用于将用户的评分和评价映射到任何人。
简单来说,是这样的:

var persons = [
  { id: '1', name: 'alice' },
  { id: '2', name: 'bob' },
  { id: '3', name: 'charlie' },
];   

var usersToPersons = [
  { userId: '1', personId: '1', hide: true },
  { userId: '1', personId: '2', hide: false },
  { userId: '7', personId: '3' },
];

我需要提取不是当前用户 'hidden' 的人。
到目前为止,我已经想出了这个(工作,但很愚蠢)功能:

function getPersonsForUser(userId) {
  var result = {};
  for (var p = 0; p < persons.length; p++) {
    for (var u = 0; u < usersToPersons.length; u++) {
      if (usersToPersons[u].userId === userId) {
        if (persons[p].id === usersToPersons[u].personId) {
          if (usersToPersons[u].hide === true) {
            console.warn('person', persons[p].name, 'skipped because this user hides it');
            break;
          } else {
            result[persons[p].id] = persons[p];
          }
        } else {
          result[persons[p].id] = persons[p];
        }
      } else {
        result[persons[p].id] = persons[p];
      }
    }
  }
  return result;
}

console.log(getPersonsForUser('1'));

结果:

person alice skipped because this user hides it
{ '2': { id: '2', name: 'bob' },
  '3': { id: '3', name: 'charlie' } }

问题是:有没有更多的fast/smart/slick方法可以按用户过滤人员?

看这里:Array prototype filter method

function getVisible(selUserId){
  var visiblePersons = persons.filter(function(v,i,a){
    var isThisPersonVisible = !usersToPersons.filter(function(vv,ii,aa){
      return (vv.personId === v.id && !vv.hide && vv.userId === selUserId || !vv.userId);
    }).length;

    return isThisPersonVisible;
  });

  return visiblePersons;
}

你可以在这里试试

demo

希望对您有所帮助

我会为此使用下划线库:

var persons = [{
  id: '1',
  name: 'alice'
}, {
  id: '2',
  name: 'bob'
}, {
  id: '3',
  name: 'charlie'
}, ];

var usersToPersons = [{
  userId: '1',
  personId: '1',
  hide: true
}, {
  userId: '1',
  personId: '2',
  hide: false
}, {
  userId: '7',
  personId: '3'
}, ];

function getPersonsForUser(userId) {
  return _.map(
    _.filter(usersToPersons,
      function(doc) {
        return doc.userId === userId && !doc.hide
      }),
    function(doc) {
      return persons[doc.personId]
    });
}

console.log(getPersonsForUser('1'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

使用 ES6 会是这样的:

let getPersonsForUser = (id) => {
  let ids = usersToPersons
      .filter(user => user.userId === id && !user.hide)
      .map(user => user.personId);

  return persons.filter(person => ids.includes(person.id));
};

你可以在 ES5 中做同样的事情,但会更冗长一些。