为了账号安全,请及时绑定邮箱和手机立即绑定

如何根据另一个数组过滤和排序对象数组

如何根据另一个数组过滤和排序对象数组

HUH函数 2023-03-24 13:45:07
我有一组用户需要根据另一个数组“过滤器”进行过滤和排序。阅读下面的代码,您可以看到预期的结果。const users = [   { key: 'abc', name: 'Anna', age: 22, gender: 'F' },   { key: 'def', name: 'John', age: 25, gender: 'M' },  { key: 'ghi', name: 'Mary', age: 27, gender: 'F' },  { key: 'jkl', name: 'Joe',  age: 30, gender: 'M' } ] const filter = [   { key: 'jkl' },  { key: 'def' },  { key: 'abc' },] // Here is the expected result:const expected_result = [   { key: 'jkl', name: 'Joe',  age: 30, gender: 'M' },  { key: 'def', name: 'John', age: 25, gender: 'M' },  { key: 'abc', name: 'Anna', age: 22, gender: 'F' }] 请考虑“key”属性是唯一的。有谁知道我该怎么做?如果您还可以解释代码背后的逻辑,我将不胜感激。我是初学者,正在为如何使用 JavaScript 函数来执行此操作而苦苦挣扎。提前致谢!
查看完整描述

4 回答

?
慕斯709654

TA贡献1840条经验 获得超5个赞

您可以将您的第一个用户数组转换为Map. Map 类似于对象,但是,它有一些差异(我在这里使用 Map,因为与对象相比,它更容易从数组构造)。

地图将具有以下形状:

Map {

  "abc": { key: 'abc', name: 'Anna', age: 22, gender: 'F' }, 

  "def": { key: 'def', name: 'John', age: 25, gender: 'M' },

  "ghi": { key: 'ghi', name: 'Mary', age: 27, gender: 'F' },

  "jkl": { key: 'jkl', name: 'Joe',  age: 30, gender: 'M' } 

}

在下面的代码中,上面的 Map 存储在一个名为lut(look-up-table 的缩写)的变量中。这样做lut.get("def")将返回存储在 key 中的对象"def",在这种情况下该对象是:


{ key: 'def', name: 'John', age: 25, gender: 'M' }

JavaScript 引擎优化了这种查找,使其非常高效,因此创建这样的 Map 有助于提高整体可伸缩性,这意味着如果您有很多用户,它会很高效。


由于输出中的顺序很重要,因此您可以使用.map()数组filter(决定顺序)将具有 name 属性的每个对象转换为我们构建的 Map 中的对象。要执行“转换”,您可以返回所需的新对象,您可以使用.get(o.key).


请参阅下面的工作示例:


const users = [{ key: 'abc', name: 'Anna', age: 22, gender: 'F' }, { key: 'def', name: 'John', age: 25, gender: 'M' }, { key: 'ghi', name: 'Mary', age: 27, gender: 'F' }, { key: 'jkl', name: 'Joe',  age: 30, gender: 'M' }]; 

const filter = [{ key: 'jkl' }, { key: 'def' }, { key: 'abc' }]; 

const expected_result = [{ key: 'jkl', name: 'Joe',  age: 30, gender: 'M' }, { key: 'def', name: 'John', age: 25, gender: 'M' }, { key: 'abc', name: 'Anna', age: 22, gender: 'F' }];


const lut = new Map(users.map(o => [o.key, o]));

const result = filter.map(f => lut.get(f.key));

console.log(result);

如果过滤器中的某个对象可以具有不在用户列表中的用户的键,则上述方法会将过滤器对象转换为“未定义”。如果你想忽略它,你可以.filter()在映射之前使用。使用.filter()将删除地图中没有键的所有过滤器对象:

const users = [{ key: 'abc', name: 'Anna', age: 22, gender: 'F' }, { key: 'def', name: 'John', age: 25, gender: 'M' }, { key: 'ghi', name: 'Mary', age: 27, gender: 'F' }, { key: 'jkl', name: 'Joe',  age: 30, gender: 'M' }]; 

const filter = [{ key: 'nonUserKey' }, { key: 'def' }, { key: 'abc' }]; 

const expected_result = [{ key: 'jkl', name: 'Joe',  age: 30, gender: 'M' }, { key: 'def', name: 'John', age: 25, gender: 'M' }, { key: 'abc', name: 'Anna', age: 22, gender: 'F' }];


const lut = new Map(users.map(o => [o.key, o]));

const result = filter.filter(o => lut.has(o.key)).map(f => lut.get(f.key));

console.log(result);


查看完整回答
反对 回复 2023-03-24
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

const users = [ 

  { key: 'abc', name: 'Anna', age: 22, gender: 'F' }, 

  { key: 'def', name: 'John', age: 25, gender: 'M' },

  { key: 'ghi', name: 'Mary', age: 27, gender: 'F' },

  { key: 'jkl', name: 'Joe',  age: 30, gender: 'M' } 


const filter = [ 

  { key: 'jkl' },

  { key: 'def' },

  { key: 'abc' },


function sort(user, filter) {

  var results = [];

  filter.forEach(obj => {

      user.forEach(obj2 => {

          if (obj.key == obj2.key) {

            results.push(obj2);

}

          })

      })

return results;

  }

  console.log(sort(users, filter))


查看完整回答
反对 回复 2023-03-24
?
繁花不似锦

TA贡献1851条经验 获得超4个赞

一个非常有效的解决方案是将数组转换filter为地图,然后使用它来过滤用户:


const users = [ 

  { key: 'abc', name: 'Anna', age: 22, gender: 'F' }, 

  { key: 'def', name: 'John', age: 25, gender: 'M' },

  { key: 'ghi', name: 'Mary', age: 27, gender: 'F' },

  { key: 'jkl', name: 'Joe',  age: 30, gender: 'M' } 


const filter = [ 

  { key: 'jkl' },

  { key: 'def' },

  { key: 'abc' },


const keys = Object.values(filter).reduce((acc, cur) => { acc[cur.key] = true; return acc; }, {});

const result = users.filter(user => keys[user.key]);


console.log(result);


查看完整回答
反对 回复 2023-03-24
?
撒科打诨

TA贡献1934条经验 获得超2个赞

您可以尝试这种方法:

逻辑:

  • filters使用签名创建地图:<key>: <index>

  • users使用具有索引的对象过滤数组filterIndex

  • 使用存储在中的索引对该过滤后的数组进行排序filterIndex

const users = [ { key: 'abc', name: 'Anna', age: 22, gender: 'F' }, { key: 'def', name: 'John', age: 25, gender: 'M' }, { key: 'ghi', name: 'Mary', age: 27, gender: 'F' }, { key: 'jkl', name: 'Joe',  age: 30, gender: 'M' } ] 


const filter = [ { key: 'jkl' }, { key: 'def' }, { key: 'abc' }, ];


const filterIndex = filter.reduce((acc, filterObj, index) => {

  acc[filterObj.key] = index;

  return acc;

}, {})


const result = users

  .filter(({ key }) => filterIndex[key] !== undefined)

  .sort((a, b) => {

    return filterIndex[ a.key ] - filterIndex[ b.key ]

  });


console.log(result)


查看完整回答
反对 回复 2023-03-24
  • 4 回答
  • 0 关注
  • 127 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信