如何在js中JSON数组按相同元素重新排列成一个新的JSON,求大拿帮助,整了2天了还是没弄好。。

请问大拿们,如何把json1优雅简便的重构成json2呢,具体就是想要把每个menuDate和dinnerTime同时相等的元素分为一组,重构一个json出来。可以使用jquery的。

json1:
[

{
    "menuDate": 1,
    "dinnerTime": "0",
    "num": 5
},
{
    "menuDate": 1,
    "dinnerTime": "0",
    "num": 1
},
{
    "menuDate": 1,
    "dinnerTime": "1",
    "num": 3
},
{
    "menuDate": 2,
    "dinnerTime": "0",
    "num": 3
},
{
    "menuDate": 2,
    "dinnerTime": "0",
    "num": 6
}

]

json2:
[

{
    "menuDate": 1,
    "dinnerTime": "0",
    "value": [
        {
            "menuDate": 1,
            "dinnerTime": "0",
            "num": 5
        },
        {
            "menuDate": 1,
            "dinnerTime": "0",
            "num": 1
        }
    ]
},
{
    "menuDate": 1,
    "dinnerTime": "1",
    "value": [
        {
            "menuDate": 1,
            "dinnerTime": "1",
            "num": 3
        }
    ]
},
{
    "menuDate": 2,
    "dinnerTime": "0",
    "value": [
        {
            "menuDate": 2,
            "dinnerTime": "0",
            "num": 3
        },
        {
            "menuDate": 2,
            "dinnerTime": "0",
            "num": 6
        }
    ]
}

]

阅读 7.6k
5 个回答

我先说说思路,首先json1 肯定需要遍历:

for (var i = 0; i < json1.length; i++) {
    var json1Elem = json1[i];
}

如上,假设现在遍历到json1 的第i个元素,如果json2 中没有找到与之相同的menudatedinnerTime,说明这是json1 第一次遇到这个两个值,就为json2 新增一个元素:

json2.push({
    "menuDate": json1Elem.menuDate,
    "dinnerTime": json1Elem.dinnerTime,
    "value": [json1Elem]
});

如果找到相同的呢?说明之前已经添加过了,假设json2 中这个相同的元素索引号为j,那么:

json2[j].value.push(json1Elem);

思路有了,现在要解决两个问题:

  1. 怎么判断json2 中是否存在某个元素与json1Elem 有相同的menudatedinnerTime

  2. 假设找到拥有相同的menudatedinnerTime的元素,这个元素的索引号j是多少呢?

我的做法是新建一个keyMap对象,menudatedinnerTime的值结合在一起作为keyMap的key,这个key是判断是否相同的唯一的依据;然后key的值是上面提到的j。整个例子的代码是:

var json2 = [];
var keyMap = {};
for (var i = 0; i < json1.length; i++) {
  var json1Elem = json1[i];
  var elemKey = json1Elem.menuDate + '-' + json1Elem.dinnerTime; // 用&或者_也可以
  if (elemKey in keyMap) {
    json2[keyMap[elemKey]].value.push(json1Elem);
  } else {
    
    json2.push({
      "menuDate": json1Elem.menuDate,
      "dinnerTime": json1Elem.dinnerTime,
      "value": [json1Elem]
    });
    keyMap[elemKey] = json2.length - 1;
  }
}

上面的代码中,elemKeymenudatedinnerTime的结合,如果这个键存在,说明之前已经添加过相同menudatedinnerTime的json1 元素了;
如果不存在,那就加一下;这里我把json2.length - 1的值赋给keyMap[elemKey],这个值正是j的值(刚刚push 进去),因此:

json2[keyMap[elemKey]].value.push(json1Elem);

就是

json2[j].value.push(json1Elem);

新建一个json数组a,遍历json1,如果在a中有相同的menudate,dinnertime 组合,则把他们以json的格式存进进数组,否则不存,这样a中存进的都是menudate和dinnertime不一样的组合,这将是判定json2不同分组的重要依据,如果a的长度为2,那么经过处理后的json2只会有两个,剩下来就是便利筛选了,手机手打 若有不对之处,望莫喷

建新对象 jnew={1_2:[],0_1:[]},1_2是 menuDate与dinnerTime的组合,在遍历原json时,根据 menuDate与dinnerTime组合成key,存入jmap,存入时判断一下是新值直接存入,已经有值则将值push入相应数组。遍历完成后,很容易根据jmap生成新json。不知道说明白没,请看代码,result即为所最后结果,在node.js平台测试正确:

var j1 = [
    {
        "menuDate": 1,
        "dinnerTime": "0",
        "num": 5
    },
    {
        "menuDate": 1,
        "dinnerTime": "0",
        "num": 1
    },
    {
        "menuDate": 1,
        "dinnerTime": "1",
        "num": 3
    },
    {
        "menuDate": 2,
        "dinnerTime": "0",
        "num": 3
    },
    {
        "menuDate": 2,
        "dinnerTime": "0",
        "num": 6
    }
]
var jmap = {};
var result = [];

j1.forEach(function(al){
    var key = al.menuDate + '_' + al.dinnerTime;
    if(typeof jmap[key] === 'undefined'){
        jmap[key] = [];
    }
    jmap[key].push(al);
})

var keys = Object.keys(jmap);
for(var i = 0; i < keys.length; i++){
    var rs = keys[i].split('_');
    result.push({menuDate:rs[0],dinnerTime:rs[1],value:jmap[keys[i]]});
}
            var originArr = [{
                "menuDate": 1,
                "dinnerTime": "0",
                "num": 5
            }, {
                "menuDate": 1,
                "dinnerTime": "0",
                "num": 1
            }, {
                "menuDate": 1,
                "dinnerTime": "1",
                "num": 3
            }, {
                "menuDate": 2,
                "dinnerTime": "0",
                "num": 3
            }, {
                "menuDate": 2,
                "dinnerTime": "0",
                "num": 6
            }];
            var ObjMap= {};

            function Obj(menuDate, dinnerTime) {
                this.menuDate = menuDate;
                this.dinnerTime = dinnerTime;
                this.values = [];
            }
            originArr.forEach(function(ele, index, arr) {
                var key = ele.menuDate + "-" + ele.dinnerTime;
                //若ObjMap[key] 为undefined 就新建一个
                if (!ObjMap[key]) {
                    ObjMap[key] = new Obj(ele.menuDate, ele.dinnerTime);
                }
                ObjMap[key].values.push(ele);
            });
            var newArr = [];
            var key;
            for (key in ObjMap) {
                newArr.push(templateObj[key]);
            }

那个newArr就是你想要的json2
中的思路就是这样

1.遍历json1.对每个obj生成一个唯一可辨识的key。
2.把js的object 当做map使用。如果可以用es6可以直接new Map对象。
3.通过key来查看ObjMap中是否存在元素,存在就直接添加到values数组里面,不存在就new一个;
4.在通过 for-in循环把 ObjMap里面说有的值添加到一个数组里面去。

        

var arr = [{
            "menuDate": 1,
            "dinnerTime": "0",
            "num": 5
            },
            {
                "menuDate": 1,
                "dinnerTime": "0",
                "num": 1
            },
            {
                "menuDate": 1,
                "dinnerTime": "1",
                "num": 3
            },
            {
                "menuDate": 2,
                "dinnerTime": "0",
                "num": 3
            },
            {
                "menuDate": 2,
                "dinnerTime": "0",
                "num": 6
            }];
        var map = {};
        for(var i = 0, len = arr.length; i < len; i++) {
            var obj = arr[i],
                menuDate = arr[i]['menuDate'],
                dinnerTime = arr[i]['dinnerTime'];
            map[menuDate] = (map.hasOwnProperty(menuDate)) ? map[menuDate]: {};
            map[menuDate][dinnerTime] = (map[menuDate].hasOwnProperty(dinnerTime)) ? map[menuDate][dinnerTime] : [];
            map[menuDate][dinnerTime].push(obj['num']);
        }
        var r = [];
        for(var menuDate in map) {
            for(var dinnerTime in map[menuDate]) {
                var ob = {
                    menuDate: menuDate,
                    dinnerTime: dinnerTime,
                    value: []
                }
                for(var i = 0, len = map[menuDate][dinnerTime].length; i < len; i++) {
                    var o = {
                        menuDate: menuDate,
                        dinnerTime: dinnerTime,
                        num: map[menuDate][dinnerTime][i]
                    };
                    ob.value.push(o);
                }
                r.push(ob);
            }
        }
        console.log(r);
推荐问题
宣传栏