javascript - js物件數組屬性合併的問題
我想大声告诉你
我想大声告诉你 2017-05-19 10:36:44
0
3
814

在做一個題目選項的功能時,遇到這個合併的問題,題目有單選和多選,單選沒問題,每題就一個答案,多選就會出現多個答案。選擇結果類似下圖:

#我需要把同一個多選題的資料合併成一個,就是圖中藍色框選部分的物件合併為一個,option變成"捏,擠",其他的Id不用管。有什麼簡單的方法實作。跪謝!

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

全部回覆(3)
为情所困

一個基本思路,先把資料遍歷一遍,相同問題的題目存為一個數組,然後遍歷處理相同題目的數組,將答案拼接即可。

範例:
資料:

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反而負複雜了。

由於不需要分類的題目數據,所以可以直接拼接答案,不用先歸類了,實現如下:

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是一個物件的形式,如果需要數組,再處理即可。

還是要贊同三樓的一點。即使是多選題,原始資料也不該是你所列的那種組織方式。 直接在統計多選題已選答案時就處理好,不是更好的方式嗎?

漂亮男人

提供一個好玩的思路,能實現,但不一定適用於真實場景;
定義一個空對象,循環遍歷數組,然後空對象的屬性名為title對應的值也就是題目; 值為一個數組,把選項push進去,當然這在每一題中可能還會牽涉到去重的問題,最後的結果大概類似這樣

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

如果可以用es6的話推薦Map

巴扎黑

1樓的方法就能解決這個問題,
2樓的map不需要非得es6
3樓拒絕回答這個問題, 因為他覺得這種實現方式不太對

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板