Javascript将条件合并行

时间:2019-10-23 20:59:30

标签: javascript arrays algorithm

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

  • 如果行中col的值相同:0、1、3、4、5,并且col 3等于特定值(例如17007)-> merge,合并后的行具有col 2的总和。
  • 否则,请不要合并。

我已经尝试过了:

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

但是它仍然不起作用。

1 个答案:

答案 0 :(得分:1)

您需要拿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; }