在做一个题目选项的功能时,遇到这个合并的问题,题目有单选和多选,单选没问题,每题就一个答案,多选就会出现多个答案。选择结果类似下图:
我需要把同一个多选题的数据合并成一个,就是图中蓝色框选部分的对象合并为一个,option变成"捏,挤",其他的Id不用管。有什么简单的方法实现。跪谢!
一个基本思路,先把数据遍历一遍,相同问题的题目存为一个数组,然后遍历处理相同题目的数组,将答案拼接即可。
示例:数据:
var questions = [{ id: Math.random() * 100000 >> 0, option: 'x', questionId: 1, title: '你的名字' }, { id: Math.random() * 100000 >> 0, option: '动作1', questionId: 2, title: '你喜欢的动作' }, { id: Math.random() * 100000 >> 0, option: '动作2', questionId: 2, title: '你喜欢的动作' }, { id: Math.random() * 100000 >> 0, option: '动作3', questionId: 2, title: '你喜欢的动作' }, { id: Math.random() * 100000 >> 0, option: '动作4', questionId: 2, title: '你喜欢的动作' }, { id: Math.random() * 100000 >> 0, option: '动作5', questionId: 2, title: '你喜欢的动作' }, { id: Math.random() * 100000 >> 0, option: '歌曲1', questionId: 3, title: '你喜欢的歌曲' }, { id: Math.random() * 100000 >> 0, option: '歌曲2', questionId: 3, title: '你喜欢的歌曲' }, { id: Math.random() * 100000 >> 0, option: '歌曲3', questionId: 3, title: '你喜欢的歌曲' }];
// 给相同题目分类
// 给相同题目分类 var categories = {}; questions.forEach(function (item, i) { if (!categories[item.questionId]) { categories[item.questionId] = [item]; } else { categories[item.questionId].push(item); } }); console.log(JSON.stringify(categories, 0, 2)); // { // "1": [ // { // "id": 76350, // "option": "x", // "questionId": 1, // "title": "你的名字" // } // ], // "2": [ // { // "id": 42682, // "option": "动作1", // "questionId": 2, // "title": "你喜欢的动作" // }, // { // "id": 19378, // "option": "动作2", // "questionId": 2, // "title": "你喜欢的动作" // }, // { // "id": 25613, // "option": "动作3", // "questionId": 2, // "title": "你喜欢的动作" // }, // { // "id": 25020, // "option": "动作4", // "questionId": 2, // "title": "你喜欢的动作" // }, // { // "id": 70897, // "option": "动作5", // "questionId": 2, // "title": "你喜欢的动作" // } // ], // "3": [ // { // "id": 38775, // "option": "歌曲1", // "questionId": 3, // "title": "你喜欢的歌曲" // }, // { // "id": 50039, // "option": "歌曲2", // "questionId": 3, // "title": "你喜欢的歌曲" // }, // { // "id": 71712, // "option": "歌曲3", // "questionId": 3, // "title": "你喜欢的歌曲" // } // ] // }
对相同类型的题目进行遍历,后面的都放到第一个里面即可。 并重新按照原格式存放
// 用于按照原格式存放最后的数据 var data =[]; for (var key in categories) { var i, l; if (categories.hasOwnProperty(key)) { for (i = 1; i < categories[key].length; ++i) { // 第一个的值 = ',' + 下一个的值 categories[key][0].option += ',' + categories[key][i].option; // 删除下一个 categories[key].splice(i, 1); --i; } data.push(categories[key][0]); } } console.log('categories',JSON.stringify(categories, null, 2)); console.log('data',JSON.stringify(data, null, 2)); // 'categories' { // "1": [ // { // "id": 72749, // "option": "x", // "questionId": 1, // "title": "你的名字" // } // ], // "2": [ // { // "id": 33498, // "option": "动作1,动作2,动作3,动作4,动作5", // "questionId": 2, // "title": "你喜欢的动作" // } // ], // "3": [ // { // "id": 79801, // "option": "歌曲1,歌曲2,歌曲3", // "questionId": 3, // "title": "你喜欢的歌曲" // } // ] // } // 'data' [ // { // "id": 72749, // "option": "x", // "questionId": 1, // "title": "你的名字" // }, // { // "id": 33498, // "option": "动作1,动作2,动作3,动作4,动作5", // "questionId": 2, // "title": "你喜欢的动作" // }, // { // "id": 79801, // "option": "歌曲1,歌曲2,歌曲3", // "questionId": 3, // "title": "你喜欢的歌曲" // } // ]
看了2楼的回答,其实之前的过程可以简化,不过确实如3楼所言,和ES6的map没有什么关系。我用了ES5的forEach。不用ES5,只用ES3,换成普通for循环完全没有问题的。使用map反而负复杂了。
forEach
由于不需要分类的题目数据,所以可以直接拼接答案,不用先归类了,实现如下:
var data2 = {}; questions.forEach(function (item, i) { if (!data2[item.questionId]) { data2[item.questionId] = item; } else { data2[item.questionId].option += ',' + item.option; } }); console.log(JSON.stringify(data2,null,2)); // { // "1": { // "id": 60348, // "option": "x", // "questionId": 1, // "title": "你的名字" // }, // "2": { // "id": 33956, // "option": "动作1,动作2,动作3,动作4,动作5", // "questionId": 2, // "title": "你喜欢的动作" // }, // "3": { // "id": 48194, // "option": "歌曲1,歌曲2,歌曲3", // "questionId": 3, // "title": "你喜欢的歌曲" // } // }
这样出来的data2是一个对象的形式,如果需要数组,再处理即可。
data2
还是要赞同三楼的一点。即使是多选题,原数据也不该是你所列的那种组织方式。直接在统计多选题已选答案时就处理好,不是更好的方式吗?
提供一个好玩的思路,能实现,但不一定适用于真实场景;定义一个空对象,循环遍历数组,然后空对象的属性名为 title对应的值也就是题目; 值为一个数组,把选项push进去,当然这在每一道题中可能还会涉及到去重的问题,最后的结果大概类似这样
obj['动作'] = ['抓','捏'];
如果可以用es6的话推荐Map
1楼的方法就能解决这个问题, 2楼的map不需要非得es63楼拒绝回答这个问题, 因为他觉得这种实现方式不太对
一个基本思路,先把数据遍历一遍,相同问题的题目存为一个数组,然后遍历处理相同题目的数组,将答案拼接即可。
示例:
数据:
// 给相同题目分类
对相同类型的题目进行遍历,后面的都放到第一个里面即可。
并重新按照原格式存放
更新
看了2楼的回答,其实之前的过程可以简化,不过确实如3楼所言,和ES6的map没有什么关系。我用了ES5的
forEach
。不用ES5,只用ES3,换成普通for循环完全没有问题的。使用map反而负复杂了。由于不需要分类的题目数据,所以可以直接拼接答案,不用先归类了,实现如下:
这样出来的
data2
是一个对象的形式,如果需要数组,再处理即可。还是要赞同三楼的一点。即使是多选题,原数据也不该是你所列的那种组织方式。直接在统计多选题已选答案时就处理好,不是更好的方式吗?
提供一个好玩的思路,能实现,但不一定适用于真实场景;
定义一个空对象,循环遍历数组,然后空对象的属性名为 title对应的值也就是题目; 值为一个数组,把选项push进去,当然这在每一道题中可能还会涉及到去重的问题,最后的结果大概类似这样
如果可以用es6的话推荐Map
1楼的方法就能解决这个问题,
2楼的map不需要非得es6
3楼拒绝回答这个问题, 因为他觉得这种实现方式不太对