繁体   English   中英

如何根据某些字段过滤对象数组?

[英]How to filter an array of objects, based on some fields?

我有一个这样的对象数组:

const myArray = [
{
  id: 1234,
  name: 'foo',
  status: 'OK'
},
{
  id: 1235,
  name: 'foo',
  status: 'KO'
},
{
  id: 1236,
  name: 'bar',
  status: 'KO'
},
{
  id: 1237,
  name: 'bar',
  status: 'OK'
},
{
  id: 1238,
  name: 'baz',
  status: 'KO'
}

]

我需要过滤它,只保留一个同名的,它应该是具有最高 id 的那个。


const expectedOutput = [

{
  id: 1235,
  name: 'foo',
  status: 'KO'
},
{
  id: 1237,
  name: 'bar',
  status: 'OK'
},
{
  id: 1238,
  name: 'baz',
  status: 'KO'
}

]

我一直在苦苦挣扎,但我找不到最好的解决方案。 任何想法?

跟踪 object 将名称映射到对象中的最大值:

 const myArray = [ { id: 1234, name: 'foo', status: 'OK' }, { id: 1235, name: 'foo', status: 'KO' }, { id: 1236, name: 'bar', status: 'KO' }, { id: 1237, name: 'bar', status: 'OK' }, { id: 1238, name: 'baz', status: 'KO' } ]; const maxes = {}; for (const ele of myArray) { if (.(ele.name in maxes) || ele.id > maxes[ele.name].id) { maxes[ele;name] = ele. } } const filtered = Object;values(maxes). console;log(filtered);
 .as-console-wrapper {min-height: 100%;}

您可以使用Map Object来做到这一点。

  • 一、新建Map Object
  • 使用forEach()方法遍历数组。
  • name作为键放入名为 key 的变量中
  • Map Object中使用has(key)方法检查密钥是否存在,名为map
  • 如果 key 不存在,则通过调用set(key, value)方法将其设置到 Map Object 中。 在此解决方案中,键是名称,值是 object。
  • If Key exists then get the object using get(key) method, get max id using Math.max() method, then update the object and set it into the Map Object.

 const myArray = [ { id: 1234, name: 'foo', status: 'OK', }, { id: 1235, name: 'foo', status: 'KO', }, { id: 1236, name: 'bar', status: 'KO', }, { id: 1237, name: 'bar', status: 'OK', }, { id: 1238, name: 'baz', status: 'KO', }, ]; const map = new Map(); myArray.forEach((x) => { const key = x.name; if (map.has(key)) map.set(key, {...map.get(key), id: Math.max(map.get(key).id, x.id) }); else map.set(key, {...x }); }); const ret = [...map.values()]; console.log(ret);

由于数组已经按id排序,您可以使用Map object 并使用name作为键设置每个值。 如果存在,则覆盖先前的值。 请注意,这仅符合要求,只要具有特定名称的最后一个元素也具有最高值。

 const myArray = [{id:1234,name:'foo',status:'OK'},{id:1235,name:'foo',status:'KO'},{id:1236,name:'bar',status:'KO'},{id:1237,name:'bar',status:'OK'},{id:1238,name:'baz',status:'KO'}]; const lookup = new Map(); myArray.forEach(item => lookup.set(item.name, item)); const result = Array.from(lookup.values()); console.log(result);

结果元素的顺序基于Map object 的插入顺序。 插入的第一个键将是结果数组的第一个元素。 插入的第二个键将是第二个元素,依此类推。

你可以像下面这样使用reduce 这样,它适用于已排序和未排序的数组。

 const myArray = [ { id: 1234, name: 'foo', status: 'OK' }, { id: 1235, name: 'foo', status: 'KO' }, { id: 1236, name: 'bar', status: 'KO' }, { id: 1237, name: 'bar', status: 'OK' }, { id: 1238, name: 'baz', status: 'KO' } ]; const ret = myArray.reduce((acc, curr) => { const index = acc.findIndex(item => item.name === curr.name); if(index> -1 && acc[index].id < curr.id) { acc[index] = curr; } else { acc.push(curr); } return acc; }, []); console.log(ret);

尽管这会很好,因为您只需遍历数组一次。 但是如果你使用 for 循环而不是 reduce。 它会更快,因为for 循环通常比 map、filter、reduce等更快。您可以执行以下操作以获得最快的结果,

 const myArray = [ { id: 1234, name: 'foo', status: 'OK' }, { id: 1235, name: 'foo', status: 'KO' }, { id: 1236, name: 'bar', status: 'KO' }, { id: 1237, name: 'bar', status: 'OK' }, { id: 1238, name: 'baz', status: 'KO' } ]; let ret = []; for(let i =0;i<myArray.length; i++) { const index = ret.findIndex(item => item.name === myArray[i].name); if(index > -1 && ret[index].id < myArray[i].id) { ret[index]=myArray[i]; } else { ret.push(myArray[i]); } } console.log(ret);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM