通过制定的key,来合并json

今天在stackoverflow上面看到的一个问题,我就自己做了做~由于stackoverflow不提倡直接给代码,只提倡给思路,我的英语又烂,表达不清楚,所以我就写在这里,以供以后学习使用。


原题:

I have a Json Structure like below

    [
      {
        "category_id": "C1",
        "category_name": "C1_Name",
        "item_id": "C1_I1",
        "item_name": "C1_I1_Name",
        "variant_id": "C1_I1_V1",
        "variant_name": "C1_I1_V1_ Name"
      },
      {
        "category_id": "C1",
        "category_name": "C1_Name",
        "item_id": "C1_I1",
        "item_name": "C1_I1_Name",
        "variant_id": "C1_I1_V2",
        "variant_name": "C1_I1_V2_ Name"
      },
      {
        "category_id": "C1",
        "category_name": "C1_Name",
        "item_id": "C1_I2",
        "item_name": "C1_I2_Name",
        "variant_id": "C1_I2_V1",
        "variant_name": "C1_I2_V1_ Name"
      },
      {
        "category_id": "C1",
        "category_name": "C1_Name",
        "item_id": "C1_I2",
        "item_name": "C1_I2_Name",
        "variant_id": "C1_I2_V2",
        "variant_name": "C1_I2_V2_ Name"
      },
      {
        "category_id": "C2",
        "category_name": "C2_Name",
        "item_id": "C2_I1",
        "item_name": "C2_I1_Name",
        "variant_id": "C2_I1_V1",
        "variant_name": "C2_I1_V1_ Name"
      }
    ]

I would Like to Group the Json to N' level in javascript , Say by passing the list of keys (say by giving category_id,item_id,variant_id , am expecting the following response)

    [
      {
        "category_id": "C1",
        "category_name": "C1_Name",
        "item": [
          {
            "item_id": "C1_I1",
            "item_name": "C1_I1_Name",
            "variant": [
              {
                "variant_id": "C1_I1_V1",
                "variant_name": "C1_I1_V1_ Name"
              },
              {
                "variant_id": "C1_I1_V2",
                "variant_name": "C1_I1_V2_ Name"
              }
            ]
          },
          {
            "item_id": "C1_I2",
            "item_name": "C1_I2_Name",
            "variant": [
              {
                "variant_id": "C1_I2_V1",
                "variant_name": "C1_I2_V1_ Name"
              },
              {
                "variant_id": "C1_I2_V2",
                "variant_name": "C1_I2_V2_ Name"
              }
            ]
          }
        ]
      }
    ]



上答案:

原理很简单,就是先按照给定的key进行分组,然后对每组在查看有没有相同value的key,如果有的话,列出来。然后循环整理。

 var json =   [
          {
            "category_id": "C1",
            "category_name": "C1_Name",
            "item_id": "C1_I1",
            "item_name": "C1_I1_Name",
            "variant_id": "C1_I1_V1",
            "variant_name": "C1_I1_V1_ Name"
          },
          {
            "category_id": "C1",
            "category_name": "C1_Name",
            "item_id": "C1_I1",
            "item_name": "C1_I1_Name",
            "variant_id": "C1_I1_V2",
            "variant_name": "C1_I1_V2_ Name"
          },
          {
            "category_id": "C1",
            "category_name": "C1_Name",
            "item_id": "C1_I2",
            "item_name": "C1_I2_Name",
            "variant_id": "C1_I2_V1",
            "variant_name": "C1_I2_V1_ Name"
          },
          {
            "category_id": "C1",
            "category_name": "C1_Name",
            "item_id": "C1_I2",
            "item_name": "C1_I2_Name",
            "variant_id": "C1_I2_V2",
            "variant_name": "C1_I2_V2_ Name"
          },
          {
            "category_id": "C2",
            "category_name": "C2_Name",
            "item_id": "C2_I1",
            "item_name": "C2_I1_Name",
            "variant_id": "C2_I1_V1",
            "variant_name": "C2_I1_V1_ Name"
          }
        ];

        Array.prototype.remove = function(item) {
            var index = this.indexOf(item);
            if(index != -1)
                this.splice(this.indexOf(item), 1);
            return this;
        }

        function findSameValue(array) {
            if(array.length <= 1) return array;

            // list all the keys
            var keys = [];
            var resultKeys = [];
            for(var key in array[0]) {
                keys.push(key);
                resultKeys.push(key);
            }

            // get the keys with same value
            keys.forEach(function(key, index){
                var current = array[0][key];

                array.forEach(function(value, index){
                    if(index == 0) return true;
                    if(value[key] != current) {
                        resultKeys.remove(key);
                        return false;
                    }
                });
            });
            return resultKeys;
        }

        function recursive(array, groupKeys, index){
            if(groupKeys.length == index) return array;

            // get the current key
            var groupKey = groupKeys[index];

            // group the array by key
            var map = {};
            var size = 0;

            array.forEach(function(obj){
                var value = obj[groupKey];
                if(!map[value]) {
                    map[value] = [];
                    size ++ ;
                }
                map[value].push(obj);
            });

            // if all the objects in the array have different value, then do not need to group it
            if(size == array.length) {
                return array;
            }

            var result = [];
            
            for(var key in map) {
                var value = map[key];
                if(value.length == 1) {
                    // if only on element, do not need further group
                    result.push(value[0]);
                } else {
                    var obj = {};
                    obj[groupKey] = key;

                    // list other keys with same value
                    var keys = findSameValue(value);

                    // get rid of the keys in the props
                    keys = keys.filter(function(key){
                        return groupKeys.indexOf(key) == -1;
                    });                 

                    // insert the key and value
                    keys.forEach(function(key){
                        if(key != groupKey) {
                            obj[key] = value[0][key];
                        }
                    });

                    // delete the keys in the objects
                    value = value.map(function(v){
                        keys.forEach(function(key){
                            delete v[key];
                        });
                        return v;
                    });

                    // recursively group the array
                    obj["items"] = recursive(value, groupKeys, index + 1);
                    result.push(obj);
                }
            }
            return result;
        };

        console.log(recursive(json, ["category_id", "item_id", "variant_id" ], 0));


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值