【问题标题】:JavaScript array of objects - remove duplicate objects from an array based on nested objectJavaScript 对象数组 - 基于嵌套对象从数组中删除重复对象
【发布时间】:2020-04-15 16:47:32
【问题描述】:

我有一个包含嵌套类别对象的对象数组(见下文)。我想删除重复的对象(基于“objectID”)并创建一个新数组,其中仅包含具有更多嵌套“hierarchicalCategories”键值对的对象

const objectsArray = [

{
  "objectID": 1234,
  "hierarchicalCategories": {
    "lvl0": "Women's",
    "lvl1": "Women's > Shirts",
    "lvl2": "Women's > Shirts > Tees"
  }
},
{
  "objectID": 5678,
  "hierarchicalCategories": {
    "lvl0": "Men's"
  }
},
{
  "objectID": 1234,
  "hierarchicalCategories": {
    "lvl0": "Women's"
  }
},
{
  "objectID": 5678,
  "hierarchicalCategories": {
    "lvl0": "Men's",
    "lvl1": "Men's > Shoes"
  }
}

]

所以预期的结果如下所示:最终数组将过滤重复项并保留每个对象的一个​​实例...“objectID”:1234 个实例,其中“hierarchicalCategories”最多为“lvl2”和“objectID” : 5678 个实例,其中 "hierarchicalCategories" 达到 "lvl1"

const newArray = [

{
  "objectID": 1234,
  "hierarchicalCategories": {
    "lvl0": "Women's",
    "lvl1": "Women's > Shirts",
    "lvl2": "Women's > Shirts > Tees"
  }
},
{
  "objectID": 5678,
  "hierarchicalCategories": {
    "lvl0": "Men's",
    "lvl1": "Men's > Shoes"
  }
}

]

我有这个函数,它适用于基于过滤重复 objectID 的新数组,但我不确定如何创建逻辑以使对象具有更多“hierarchicalCategories”键值对。

     const newArray = Array.from(new Set(objectsArray.map(a => a.objectID)))
                .map(objectID => {
                    return objectsArray.find(a => a.objectID === objectID)
         })

【问题讨论】:

  • 什么不起作用?请添加您的代码。
  • @NinaScholz 我更新了我的答案以包含一个用于过滤重复 objectID 的函数,但我不确定如何根据嵌套对象中“hierarchicalCategories”的数量进行过滤

标签: javascript arrays


【解决方案1】:

您可以使用Map 并将类别分配到同一组。

const
    objectsArray = [{ objectID: 1234, hierarchicalCategories: { lvl0: "Women's", lvl1: "Women's > Shirts", lvl2: "Women's > Shirts > Tees" } }, { objectID: 5678, hierarchicalCategories: { lvl0: "Men's" } }, { objectID: 1234, hierarchicalCategories: { lvl0: "Women's" } }, { objectID: 5678, hierarchicalCategories: { lvl0: "Men's", lvl1: "Men's > Shoes" } }],
    result = Array.from(objectsArray
        .reduce((m, o) => {
            if (m.has(o.objectID)) {
                Object.assign(m.get(o.objectID).hierarchicalCategories, o.hierarchicalCategories);
                return m;
            }
            return m.set(o.objectID, o);            
        }, new Map)
       .values()
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

一种更短的方法,直接收集类别并从收集的部分构建新对象。

const
    objectsArray = [{ objectID: 1234, hierarchicalCategories: { lvl0: "Women's", lvl1: "Women's > Shirts", lvl2: "Women's > Shirts > Tees" } }, { objectID: 5678, hierarchicalCategories: { lvl0: "Men's" } }, { objectID: 1234, hierarchicalCategories: { lvl0: "Women's" } }, { objectID: 5678, hierarchicalCategories: { lvl0: "Men's", lvl1: "Men's > Shoes" } }],
    result = Array.from(
        objectsArray.reduce((m, { objectID: id, hierarchicalCategories: o }) => 
            m.set(id, Object.assign((m.get(id) || {}), o)), new Map),
       ([objectID, hierarchicalCategories]) => ({ objectID, hierarchicalCategories })
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    使用.sort().filter() 从最高级别到最低级别排序并进行过滤,以便只有最高级别的级别在新数组中。

    const objectsArray = [
    
      {
        "objectID": 1234,
        "hierarchicalCategories": {
          "lvl0": "Women's",
          "lvl1": "Women's > Shirts",
          "lvl2": "Women's > Shirts > Tees"
        }
      },
      {
        "objectID": 5678,
        "hierarchicalCategories": {
          "lvl0": "Men's"
        }
      },
      {
        "objectID": 1234,
        "hierarchicalCategories": {
          "lvl0": "Women's"
        }
      },
      {
        "objectID": 5678,
        "hierarchicalCategories": {
          "lvl0": "Men's",
          "lvl1": "Men's > Shoes"
        }
      }
    ]
    const newArray = objectsArray.sort((a, b) => Object.keys(b.hierarchicalCategories).length - Object.keys(a.hierarchicalCategories).length).filter((v, i, a) => i === a.findIndex(e => e.objectID === v.objectID));
    
    console.log(newArray);
    .as-console-wrapper {
      max-height: 100% !important;
      top: 0;
    }

    【讨论】:

      【解决方案3】:
      const shouldAdd = (item, target) => {
        if (!target[item.objectID]) return true;
        if (target[item.objectID] && !target[item.objectID].hierarchicalCategories && item.hierarchicalCategories) return true;
        if (target[item.objectID] && target[item.objectID].hierarchicalCategories && item.hierarchicalCategories && Object.keys(target[item.objectID].hierarchicalCategories).length < Object.keys(item.hierarchicalCategories).length) return true;
      }
      
      let newObjectsArray = {}
      objectsArray.forEach((obj) => {
        if (shouldAdd(obj, newObjectsArray)) {
          newObjectsArray[obj.objectID] = obj
        }
      })
      
      console.log(Object.values(newObjectsArray)); //Object.values(newObjectsArray) should contain what you want 
      
      
      
      

      【讨论】:

        【解决方案4】:

        const objectsArray = [
        
        {
          "objectID": 1234,
          "hierarchicalCategories": {
            "lvl0": "Women's",
            "lvl1": "Women's > Shirts",
            "lvl2": "Women's > Shirts > Tees"
          }
        },
        {
          "objectID": 5678,
          "hierarchicalCategories": {
            "lvl0": "Men's"
          }
        },
        {
          "objectID": 1234,
          "hierarchicalCategories": {
            "lvl0": "Women's"
          }
        },
        {
          "objectID": 5678,
          "hierarchicalCategories": {
            "lvl0": "Men's",
            "lvl1": "Men's > Shoes"
          }
        }
        
        ]
        
        var result_arr = objectsArray.reduce((acc, curr) => {
            const existing_obj = acc.find(item => item.objectID === curr.objectID);
            if (existing_obj) {
                if (Object.keys(curr.hierarchicalCategories).length > Object.keys(existing_obj.hierarchicalCategories).length)
                existing_obj.hierarchicalCategories = {...curr.hierarchicalCategories };
            } else {
                acc.push(curr);
            }
            return acc;
        }, []);
        
        console.log(result_arr)

        【讨论】:

          猜你喜欢
          • 2020-12-07
          • 2019-11-15
          • 2021-12-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-02
          相关资源
          最近更新 更多