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;
}
你可以在这里试试
希望对您有所帮助
我会为此使用下划线库:
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 中做同样的事情,但会更冗长一些。
我有两个数组:一个用于人,一个用于将用户的评分和评价映射到任何人。
简单来说,是这样的:
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;
}
你可以在这里试试
希望对您有所帮助
我会为此使用下划线库:
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 中做同样的事情,但会更冗长一些。