首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

JavaScript 數組合並:按指定鍵值分組合併屬性值

     編輯:程式設計疑難解答

需求描述

給定對象數組:

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"}
];

核心算法:Map 分組法

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"}]

ES6 現代寫法(推薦)

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 reduceO(n)現代瀏覽器/Node.js,代碼簡潔

常見坑點提醒

  • 鍵類型轉換:Object 鍵默認為字串,3 與 "3" 會合併,若需區分類型請用 Map 對象。
  • 原始數組修改:上述方法均生成新數組,不修改原數組。
  • 缺失字段處理:建議添加 if (!obj[keyField]) continue; 容錯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved