[英]How to use Array.protoype.map() on array of objects to filter out some specific keys based on it's values?
[英]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
来做到这一点。
forEach()
方法遍历数组。name
作为键放入名为 key 的变量中Map Object
中使用has(key)
方法检查密钥是否存在,名为map
set(key, value)
方法将其设置到 Map Object 中。 在此解决方案中,键是名称,值是 object。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.