代码之家  ›  专栏  ›  技术社区  ›  kemotoe

基于现有对象数组的若干属性返回新的对象数组

  •  3
  • kemotoe  · 技术社区  · 6 年前

    我正在绞尽脑汁想办法实现我所需要的。我的初始对象数组是70k个对象,每个对象有15个属性。通过过滤和映射,我将数据设置为我认为相关的部分。我需要根据每个对象的4个属性返回一个新的对象数组,它们是重复的 id's 不同的 levels 为每个人 code . 我的过滤数据看起来是这样的。

    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"}]
    

    我要做到的是 id 任何人 current 属于 Y 为每个人 代码 ,我需要找到最大的 level 为了这个 代码 . 因此,对于上面的示例,结果输出将是一个对象数组,如下所示:

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

    我甚至不确定我想要的是可能的,还是我想错了。我一上午都在绞尽脑汁想办法。

    4 回复  |  直到 6 年前
        1
  •  2
  •   mickl    6 年前

    你可以用 .filter() .map() 根据 Y 然后 .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);
        2
  •  2
  •   baao    6 年前

    你可以简化成一张地图,取它的值

    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()]);
        3
  •  2
  •   amrender singh    6 年前

    你可以简单地实现 Array.reduce() Object destructuring . 构造一个映射,每个键由 id code . 简单使用 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);
        4
  •  0
  •   Pavlo    6 年前
    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,然后必须将对象中的所有值转换为一个数组