我有以下数据:
let Collection = [{
id: '1',
uid: 'u1',
rci: 'r1',
name: 'ClientName'
}, {
uid: 'u2',
name: 'ClientName 2'
}, {
rci: 'r3',
name: 'ClientName 3'
}]
id,uid和rci是三个不同的id属性(来自可怕的数据库合并)。
每个客户:
现在的问题是: 我必须使用与此类似的对象搜索此集合:
search: {
id: undefined,
uid: 'u3',
rci: 'r3'
}
与集合中的第三个条目匹配,因为rci属性匹配。
显然,有这个解决方案:
let match;
let test = Collection.forEach(item => {
Object.keys(search).forEach(key => {
console.log('iteration')
if(item[key] && item[key] === search[key]) {
match = item
}
})
})
但我正在寻找一个更优雅的解决方案。 我也在使用underscorejs。
注意:这是Immutable.js集合/地图/列表的POJO版本。如果使用Immutable.js可以实现同样的目标,那就太棒了:)
答案 0 :(得分:1)
如果我正确地阅读了您的问题,搜索应该找到与undefined
对象上的任何非search
键/值对匹配的内容(而非所有内容) )。
如果是这样,你可以通过弄清楚那些一次这些键是什么来提高效率,并在找到匹配后停止循环:
let keys = Object.keys(search).filter(key => search[key] !== undefined);
let match = _.find(Collection, item => keys.some(key => item[key] === search[key]));
从ES2015(又名ES6)或Array#find
的垫片开始,不需要任何下划线:
let keys = Object.keys(search).filter(key => search[key] !== undefined);
let match = Collection.find(item => keys.some(key => item[key] === search[key]));
我们不需要您拥有的item[key] &&
,因为我们会在开始搜索之前过滤掉undefined
值的密钥,因此如果该项目没有密钥,item[key]
不会是===
的{{1}}匹配。
这是使用Babel REPL上的示例数据的ES2015版本的live example。
答案 1 :(得分:0)
在普通的Javascript中,您可以使用Array#filter()
和Array#some()
。
function find(array, search) {
var s = {};
Object.keys(search).forEach(function (k) {
if (typeof search[k] !== 'undefined') {
s[k] = search[k];
}
});
return array.filter(function (a) {
return Object.keys(s).some(function (k) {
return s[k] === a[k];
});
});
}
var collection = [{ id: '1', uid: 'u1', rci: 'r1', name: 'ClientName' }, { uid: 'u2', name: 'ClientName 2' }, { rci: 'r3', name: 'ClientName 3' }],
result = find(collection, { id: undefined, uid: 'u3', rci: 'r3' });
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');