javascript - js object array attribute merging problem
我想大声告诉你
我想大声告诉你 2017-05-19 10:36:44
0
3
812

When I was working on a question option function, I encountered this merge problem. There are single-choice and multiple-choice questions. Single-choice is no problem. Each question has one answer. Multiple-choice will result in multiple answers. The selection result is similar to the picture below:

I need to merge the data of the same multiple-choice question into one, that is, the objects in the blue box selection part in the picture are merged into one, the option becomes "pinch, squeeze", and other IDs are ignored. Is there any simple way to achieve this. Kneel down and thank you!

我想大声告诉你
我想大声告诉你

reply all(3)
为情所困

A basic idea is to traverse the data first, save the questions of the same question as an array, then traverse the arrays dealing with the same question, and splice the answers.

Example:
Data:

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: '你喜欢的歌曲'
}];

//Category the same questions

// 给相同题目分类
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": "你喜欢的歌曲"
//     }
//   ]
// }

Traverse questions of the same type, and put all the following questions into the first one.
and re-store it in the original format

// 用于按照原格式存放最后的数据
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": "你喜欢的歌曲"
//   }
// ]

Update

After reading the answer on the 2nd floor, in fact, the previous process can be simplified, but as the 3rd floor said, it has nothing to do with the ES6 map. I used ES5 forEach. Instead of using ES5, just use ES3. There is no problem at all if you replace it with a normal for loop. Using map is quite complicated.

Since there is no need to classify the question data, the answers can be spliced ​​directly without classifying them first. The implementation is as follows:

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": "你喜欢的歌曲"
//   }
// }

What comes out like thisdata2 is in the form of an object. If you need an array, just process it.

I still have to agree with the point on the third floor. Even if it is a multiple-choice question, the original data should not be organized in the way you listed. Isn’t it a better way to handle it directly when counting the selected answers to multiple-choice questions?

漂亮男人

Provides a fun idea that can be implemented, but may not be applicable to real scenarios;
Define an empty object, loop through the array, and then the attribute of the empty object is named title and the corresponding value is the title; the value is an array, and the option Push it in. Of course, this may also involve the issue of duplication removal in each question. The final result is probably similar to this

obj['动作'] = ['抓','捏']; 

If you can use es6, I recommend Map

巴扎黑

The method on the 1st floor can solve this problem.
The map on the 2nd floor does not need to be es6.
The 3rd floor refused to answer this question because he felt that this implementation method was not right

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template