【问题标题】:Count and sort an array of objects of nested arrays by highest number of duplicates按最高重复次数对嵌套数组的对象数组进行计数和排序
【发布时间】:2018-01-24 06:15:50
【问题描述】:

这听起来可能已经得到解答,但我在 StackOverflow 上尝试了很多解决方案。没有一个能解决我的问题。我有一个复杂的嵌套数组和数据集,其中包含更多嵌套的子集或列表。我想将它们合并和/或找到一种方法来按特定键对重复项进行计数和排序。这是我拥有的真实数据: 编辑

      var arr =[  
   {  
      "Brand 1":[  
         {  
            "NAME":"SHIRT",
            "SIZE":"M"
         },
         {  
            "NAME":"PANTS",
            "SIZE":"L"
         }
      ],
      "Brand 2":[  
         {  
            "NAME":"JEANS",
            "SIZE":"S"
         },
         {  
            "NAME":"TROUSER",
            "SIZE":"S"
         },
         {  
            "NAME":"TROUSERS",
            "SIZE":"L"
         }
      ],
      "Brand 3":[  
         {  
            "SIZE":"L",
            "NAME":"JEANS"
         }
      ]
   },
   {  
      "Brand x":[  
         {  
            "NAME":"SNEAKERS",
            "SIZE":"M"
         }
      ],
      "Brand 2":[  
         {  
            "NAME":"BLAZER",
            "SIZE":"L"
         },
         {  
            "NAME":"FUR COAT",
            "SIZE":"L"
         }
      ],
      "Brand 1":[  
         {  
            "SIZE":"XL",

            "NAME":"BLAZER"
         }
      ]
   }
]

子集的数量不固定。如您所见,这是一个复杂的数组,现有的解决方案不会超过 2 个级别或 1 个维度。期望的输出: 编辑

      var arr =  [  
   {  
      "Brand 1":[  
         {  
            "NAME":"SHIRT",
            "SIZE":"M"
         },
         {  
            "NAME":"PANTS",
            "SIZE":"L"
         },
         {  
            "COUNT":"3"
         }
      ],
      "Brand 2":[  
         {  
            "NAME":"JEANS",
            "SIZE":"S"
         },
         {  
            "NAME":"TROUSER",
            "SIZE":"S"
         },
         {  
            "NAME":"TROUSERS",
            "SIZE":"L"
         },
         {  
            "COUNT":"5"
         }
      ],
      "Brand 3":[  
         {  
            "SIZE":"L",
            "NAME":"JEANS"
         },
         {  
            "COUNT":"3"
         }
      ]
   },
   {  
      "Brand x":[  
         {  
            "NAME":"SNEAKERS",
            "SIZE":"M"
         },
         {  
            "COUNT":"1"
         }
      ]
   }
]

您能看到每个品牌数组末尾的“COUNT”变量吗?这就是我想要的并根据它对项目进行排序。

我已经在 stackoveflow 上尝试过标准排序解决方案,包括连接、合并和展平。没有合适的解决方案对我有用。 提前感谢您的帮助!

【问题讨论】:

    标签: javascript jquery sorting multidimensional-array javascript-objects


    【解决方案1】:

    嵌套数据结构,尤其是在键和值之间传播信息的情况下,使用起来很痛苦。我建议您将对象转换为普通对象的平面列表(如果需要,将键放入这些对象中)并将此列表用作进一步处理的基础,例如聚合。

    这是如何进行这种转换的:

    var arr = [
        {
            "Brand 1": [
                {
                    "NAME": "SHIRT",
                    "SIZE": "M"
                },
                {
                    "NAME": "PANTS",
                    "SIZE": "L"
                }
            ],
            "Brand 2": [
                {
                    "NAME": "JEANS",
                    "SIZE": "S"
                },
                {
                    "NAME": "TROUSER",
                    "SIZE": "S"
                },
                {
                    "NAME": "TROUSERS",
                    "SIZE": "L"
                }
            ],
            "Brand 3": [
                {
                    "SIZE": "L",
                    "NAME": "JEANS"
                }
            ]
        },
        {
            "Brand x": [
                {
                    "NAME": "SNEAKERS",
                    "SIZE": "M"
                }
            ],
            "Brand 2": [
                {
                    "NAME": "BLAZER",
                    "SIZE": "L"
                },
                {
                    "NAME": "FUR COAT",
                    "SIZE": "L"
                }
            ],
            "Brand 1": [
                {
                    "SIZE": "XL",
    
                    "NAME": "BLAZER"
                }
            ]
        }
    ];
    
    // build a flat list of objects
    
    let isScalar = x => typeof x !== 'object' || x === null;
    let isPlain = x => isScalar(x) || Object.values(x).every(isScalar);
    
    function *flat(obj) {
        if (isPlain(obj))
            yield obj;
    
        else if (Array.isArray(obj))
            for (let x of obj)
                yield *flat(x);
    
        else
            for (let key of Object.keys(obj))
                for (let val of flat(obj[key]))
                    yield Object.assign(val, {key});
    }
    
    
    let all = [...flat(arr)];
    
    // aggregation examples
    
    let count = function(values) {
        let m = new Map();
        for (let x of values)
            m.set(x, (m.get(x) || 0) + 1);
        return [...m.entries()];
    }
    
    let byBrand = count(all.map(x => x.key));
    console.log(byBrand);
    
    let bySize = count(all.map(x => x.SIZE));
    console.log(bySize);

    【讨论】:

    • 感谢您的回答,但是,它在控制台中显示错误:“无法将未定义或 null 转换为对象”虽然我已经做了一个聚合器功能,但您的可能会有所不同。但是那个聚合器只是将整个数组展平,没有留下任何键和结构的痕迹。就像字符串一样简单。
    • 为什么要对我的问题投反对票?自己尝试一下,它不像那些线上的其他问题。这很复杂。我几乎尝试了所有解决方案,没有任何效果。
    • @Zafar:我已经用你发布的内容进行了测试,效果很好。你的实际数据不同吗?
    • 谢谢。它工作并且有点扁平化数组,但我仍然不知道如何将所有嵌套数组聚合成一个并计算出现次数?你的代码给了我这个:[ { "sku":"1234", "name":"Brand1", "key":"Brand1" }, { "sku":"12345", "name":"Brand1", "key":"Brand1" }, { "sku":"123456", "name":"Brand1", "key":"Brand1" }, { "sku":"008", "name":"Brand2", "key":"Brand2" }]....] 是不是和以前一样?
    • 创建一个空对象counter={},迭代数组并为每个项目执行counter[item.name] = (counter[item.name] || 0) + 1。这为您提供了每个品牌的计数。
    猜你喜欢
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 2019-10-27
    相关资源
    最近更新 更多