繁体   English   中英

基于现有对象数组的多个属性返回新的对象数组

[英]Return new array of objects based on several properties of existing array of objects

我正试图弄清楚如何实现我的需要。 我的初始对象数组是70k个对象,每个对象有15个属性。 通过过滤和映射,我将数据集下载到我认为的相关部分。 我需要根据每个对象的4个属性返回一个新的对象数组,它们是重复的id's和每个code不同levels 我的过滤数据看起来像这样。

const arr = [{id: "12345", level: "1", current: "Y", code: "1"}, 
             {id: "12345", level: "0", current: "N", code: "1"},
             {id: "54321", level: "1", current: "N", code: "201"},
             {id: "54321", level: "2", current: "Y", code: "201"}, 
             {id: "54321", level: "3", current: "N", code: "201"},
             {id: "54321", level: "0", current: "Y", code: "401"},
             {id: "54321", level: "1", current: "N", code: "401"},
             {id: "54321", level: "3", current: "N", code: "201"},
             {id: "54321", level: "0", current: "N", code: "301"},
             {id: "121212", level: "0", current: "N", code: "3"},
             {id: "121212", level: "1", current: "N", code: "3"}]

我需要实现的是每个codeY任何current的每个id ,我需要找到该code的最大level 因此,对于上面的示例,结果输出将是一个对象数组,如下所示:

const result = [{id: "12345", max: "1", code: "1"}, 
                {id: "54321", max: "3", code: "201"},
                {id: "54321", max: "1", code: "401"}]

我甚至不确定我想要的是否可行,或者我是否以错误的方式思考它。 我整个上午一直在努力寻找解决方案。

您可以使用.filter().map()来获取基于Y初始值,然后使用.filter() .reduce()来获取最大值:

 const arr = [{id: "12345", level: "1", current: "Y", code: "1"}, {id: "12345", level: "0", current: "N", code: "1"}, {id: "54321", level: "1", current: "N", code: "201"}, {id: "54321", level: "2", current: "Y", code: "201"}, {id: "54321", level: "3", current: "N", code: "201"}, {id: "54321", level: "0", current: "Y", code: "401"}, {id: "54321", level: "1", current: "N", code: "401"}, {id: "54321", level: "3", current: "N", code: "201"}, {id: "54321", level: "0", current: "N", code: "301"}, {id: "121212", level: "0", current: "N", code: "3"}, {id: "121212", level: "1", current: "N", code: "3"}] let initialValues = arr.filter(x => x.current === "Y") .map(x => ({ id: x.id, max: x.level, code: x.code })); let result = arr.reduce((result,current) => { var value = result.find(x => x.id === current.id && x.code === current.code); if(!value) return result; if(value.max < current.level) { value.max = current.level; } return result; }, initialValues); console.log(result); 

您可以简单地实现Array.reduce()Object destructuring 使用idcode的组合构造每个键的映射。 只需在地图上使用Object.values()即可获得所需的结果:

 const arr = [{id: "12345", level: "1", current: "Y", code: "1"}, {id: "12345", level: "0", current: "N", code: "1"}, {id: "54321", level: "1", current: "N", code: "201"}, {id: "54321", level: "2", current: "Y", code: "201"}, {id: "54321", level: "3", current: "N", code: "201"}, {id: "54321", level: "0", current: "Y", code: "401"}, {id: "54321", level: "1", current: "N", code: "401"}, {id: "54321", level: "3", current: "N", code: "201"}, {id: "54321", level: "0", current: "N", code: "301"}, {id: "121212", level: "0", current: "N", code: "3"}, {id: "121212", level: "1", current: "N", code: "3"}]; const result = Object.values(arr.reduce((a,{level,current, ...props})=>{ a[props.id+"_"+props.code] = a[props.id+"_"+props.code] || props; a[props.id+"_"+props.code].max = Math.max((a[props.id+"_"+props.code].max || 0), level); return a; },{})); console.log(result); 

您可以缩减为Map并获取其值

 const arr = [{id: "12345", level: "1", current: "Y", code: "1"}, {id: "12345", level: "0", current: "N", code: "1"}, {id: "54321", level: "1", current: "N", code: "201"}, {id: "54321", level: "2", current: "Y", code: "201"}, {id: "54321", level: "3", current: "N", code: "201"}, {id: "54321", level: "0", current: "Y", code: "401"}, {id: "54321", level: "1", current: "N", code: "401"}, {id: "54321", level: "3", current: "N", code: "201"}, {id: "54321", level: "0", current: "N", code: "301"}, {id: "121212", level: "0", current: "N", code: "3"}, {id: "121212", level: "1", current: "N", code: "3"}]; const res = arr.reduce((a, b) => b.current === 'Y' ? a.set(b.id + b.code, (a.get(b.id + b.code) || { level: Number.MIN_SAFE_INTEGER }).level < b.level ? b : a.get(b.id + b.code)) : a, new Map); console.log([...res.values()]); 

const resultObject = (arr, filter) => arr.reduce((sum, element) => {
  const currentInSum = sum[element.id];
  const filterSatisfied = element.current === filter;
  const isHighestLevel = !currentInSum  || currentInSum.level < element.level;
  if(filterSatisfied && isHighestLevel){
     sum[element.id] = element;
  }
  return sum;
}, {});
const result = Object.values(resultObject(arr, "Y"));

基本上你想要使用一个对象,以便你可以检查元素是否已经添加,如果当前级别高于​​已经添加的级别,则替换它,如果这是第一次出现,则只需将其添加到对象。

最后,只需从对象获取所有值以将其转换为数组,您不关心作为对象id的键。

这个算法需要O(n * 2)时间来执行,因为你必须运行arr一次,然后你必须将对象中的所有值转换为数组

暂无
暂无

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

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