給定對象數組:
var arr = [
{a: 3, b: 4},
{a: 3, b: 7},
{a: 5, b: 2},
{a: 5, b: 1}
];
需按 a 屬性分組,將相同 a 的 b 值合併為逗號分隔字串,輸出:
var result = [
{a: 3, b: "4,7"},
{a: 5, b: "2,1"}
];
function mergeArrayByKey(arr, keyField, mergeField) {
var map = {}; // 以 keyField 值為鍵
var result = [];
for (var i = 0; i < arr.length; i++) {
var obj = arr[i];
var key = obj[keyField];
var val = obj[mergeField];
if (map.hasOwnProperty(key)) {
// 已存在,追加值
map[key] += ',' + val;
} else {
// 首次出現,初始化
map[key] = val;
}
}
// 將 map 轉換為目標數組格式
for (var key in map) {
if (map.hasOwnProperty(key)) {
var newObj = {};
newObj[keyField] = key; // 注意:key 為字串,若需數字可 parseInt
newObj[mergeField] = map[key];
result.push(newObj);
}
}
return result;
}
// 使用示例
var arr = [{a:3,b:4}, {a:3,b:7}, {a:5,b:2}, {a:5,b:1}];
var merged = mergeArrayByKey(arr, 'a', 'b');
console.log(merged);
// 輸出: [{a: "3", b: "4,7"}, {a: "5", b: "2,1"}]
const mergeArrayByKey = (arr, keyField, mergeField) => {
const groups = arr.reduce((map, item) => {
const key = item[keyField];
const val = item[mergeField];
map[key] = map[key] ? `${map[key]},${val}` : val;
return map;
}, {});
return Object.entries(groups).map(([key, val]) => ({
[keyField]: isNaN(key) ? key : Number(key), // 盡量保持原類型
[mergeField]: val
}));
};
若後續需對合併值進行數學運算,建議合併為數組:
const mergeToArray = (arr, keyField, mergeField) => {
const groups = arr.reduce((map, item) => {
const key = item[keyField];
if (!map[key]) map[key] = [];
map[key].push(item[mergeField]);
return map;
}, {});
return Object.entries(groups).map(([key, vals]) => ({
[keyField]: Number(key),
[mergeField]: vals
}));
};
// 結果: [{a: 3, b: [4,7]}, {a: 5, b: [2,1]}]
| 方法 | 時間複雜度 | 適用場景 |
|---|---|---|
| 雙重循環 | O(n²) | 數據量極小(<100) |
| Map/Object 分組 | O(n) | 通用場景,推薦 |
| ES6 reduce | O(n) | 現代瀏覽器/Node.js,代碼簡潔 |
3 與 "3" 會合併,若需區分類型請用 Map 對象。if (!obj[keyField]) continue; 容錯。