首页 > 解决方案 > Javascript 将行与条件合并

问题描述

我需要合并具有特定条件的行,如下所示:

我试过这个:

const expect = require('chai').expect

// this function takes an object, check values of all compared columns (a, b, c, d, e) of each row, if there's a match, return a merged row with value col (v) = sum of each old row v
const mergeRows = (obj, v, ...params) => {
    const result = obj.reduce((acc, cur) => {
        const key = params.map(p => {return `${cur[p]}`}).join('|')
        // if the key values don't match
        if (acc[3] === '17007') {
            if(!acc[key]) acc[key] = cur
            // if the key values match
            else acc[key][v] = (+acc[key][v] + +cur[v]).toString()
        }
        else acc[key] = cur;
        return acc
    }, {})

    return Object.values(result)
}

const mergeRowsObj = [
    ['5400-030', '15051', '-77.25', '17001P', 'ARED', 'ABC'],
    ['1250-100', '15051', '230.14', '17001P', 'BGRE', 'DEF'],
    ['5400-030', '15051', '-145.5', '17007', 'CBLU', 'GHI'],
    ['1250-100', '15051', '103', '17007', 'DYEL', 'IJK'],
    ['1250-100', '15051', '-23.4', '17007', 'DYEL', 'IJK'],
    ['5400-030', '15051', '203.5', '17007', 'CBLU', 'GHI'],
    ['5400-032', '15051', '10', '17008', 'CBLU', 'GHI'],
    ['5400-032', '15051', '5', '17008', 'CBLU', 'GHI'],
    ['5400-030', '15051', '125', '17007', 'CBLU', 'GHI']
]
const mergeRowsResultObj = [
    ['5400-030', '15051', '-77.25', '17001P', 'ARED', 'ABC'],
    ['1250-100', '15051', '230.14', '17001P', 'BGRE', 'DEF'],
    ['5400-030', '15051', '183', '17007', 'CBLU', 'GHI'],
    ['1250-100', '15051', '79.6', '17007', 'DYEL', 'IJK'],
    ['5400-032', '15051', '10', '17008', 'CBLU', 'GHI'],
    ['5400-032', '15051', '5', '17008', 'CBLU', 'GHI']
]

const mergeRowsResult = mergeRows(mergeRowsObj, 2, 0, 1, 3, 4, 5)

console.log(mergeRowsResult);

describe('mergeRows', () => {
    it('should return an object with merged rows that contain the same values of specific columns', () => {
        expect(mergeRowsResult).to.deep.equal(mergeRowsResultObj)
    })
})

我还尝试修改reduce()函数以添加第 3 行值的条件,例如:

if(!acc[key] || cur[3] !== '17007') acc[key] = cur

但它仍然不起作用。

标签: javascriptarraysalgorithm

解决方案


你需要采取cur而不是acc

if (cur[3] === '17007') {
//  ^^^

以及未更改行的另一个唯一键,在这种情况下,我将完整的行作为字符串作为键。

acc[Object.values(cur).join('|')] = cur;
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

const mergeRows = (obj, v, ...params) => {
    const result = obj.reduce((acc, cur) => {
        const key = params.map(p => cur[p]).join('|')
        if (cur[3] === '17007') {
            if(!acc[key]) acc[key] = cur
            else acc[key][v] = (+acc[key][v] + +cur[v]).toString()
        } else {
            acc[Object.values(cur).join('|')] = cur;
        }
        return acc
    }, {})

    return Object.values(result)
}

const mergeRowsObj = [
    ['5400-030', '15051', '-77.25', '17001P', 'ARED', 'ABC'],
    ['1250-100', '15051', '230.14', '17001P', 'BGRE', 'DEF'],
    ['5400-030', '15051', '-145.5', '17007', 'CBLU', 'GHI'],
    ['1250-100', '15051', '103', '17007', 'DYEL', 'IJK'],
    ['1250-100', '15051', '-23.4', '17007', 'DYEL', 'IJK'],
    ['5400-030', '15051', '203.5', '17007', 'CBLU', 'GHI'],
    ['5400-032', '15051', '10', '17008', 'CBLU', 'GHI'],
    ['5400-032', '15051', '5', '17008', 'CBLU', 'GHI'],
    ['5400-030', '15051', '125', '17007', 'CBLU', 'GHI']
]

const mergeRowsResult = mergeRows(mergeRowsObj, 2, 0, 1, 3, 4, 5)

mergeRowsResult.forEach(a => console.log(...a));
.as-console-wrapper { max-height: 100% !important; top: 0; }


推荐阅读