通过与另一个对象的部分匹配来查找对象

Find object by partial match with another object

本文关键字:查找 对象 一个对象      更新时间:2023-09-26

我有以下数据:

 let Collection = [{
    id: '1',
    uid: 'u1',
    rci: 'r1',
    name: 'ClientName'
  }, {
    uid: 'u2',
    name: 'ClientName 2'
  }, {
    rci: 'r3',
    name: 'ClientName 3'
  }]

id、uid 和 rci 是三种不同的 id 属性(由糟糕的数据库合并导致(。

每个客户:

  • 至少具有以下属性之一
  • 可能同时具有所有三个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
    }
  })
}) 

但我正在寻找一个更优雅的解决方案。我也在使用下划线js。

注意:这是不可变.js集合/映射/列表的POJO版本。如果同样的事情可以用不可变实现.js那将是很好的:)

如果我

没看错你的问题,搜索应该找到与search对象(而不是全部(上任何undefined键/值对匹配的内容。

如果是这样,您可以通过一次弄清楚这些键是什么,并在找到匹配项后停止循环来提高效率:

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]将不会是search[key] ===匹配项。

下面是 ES2015 版本的一个实时示例,它使用了您在 Babel 的 REPL 上的示例数据。

在普通的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>');