在嵌套数组上获取价格乘以数量的总和

Get total sum of price amount multiplied by quantity over nested arrays

我有这样的嵌套对象数组:

[
  {
    tasks: [
      {
        requestTaskId: 'be6ee458-8ef0-11ec-912a-3d12c29b6342',
        price: 5,
      },
      {
        requestTaskId: 'be6ee502-8ef0-11ec-b81a-3d12c29b6342',
        price: 5,
      },
    ],
    request: {
      tasks: [
        {
          id: 'be6ee458-8ef0-11ec-912a-3d12c29b6342',
          quantity: 10,
        },
        {
          id: 'be6ee502-8ef0-11ec-b81a-3d12c29b6342',
          quantity: 10,
        },
      ],
    },
  },
];

而且我需要对所有任务的价格和数量求和,也checking/matching按tasks.requestTaskId === request.tasks.id条件。

结果应该是 (10 * 5) + (10 * 5) = 100。

如何使用 map /find/ reduce 得到这个?想不出更好的帮手来实现这一点,只是不知道如何组合所有东西。

这是我尝试过的:

  array.map((item) => ({
      ...item,
      ...item.request.tasks.find((requestTask) => ({
        ...requestTask,
        ...item.tasks.find(({ requestTaskId }) => requestTaskId === requestTask.id),
      })),
    }))
    .map(({ amount, quantity})) => ({
      total: amount * quantity,
    });

这是一个示例,您的给定数据假设顶层对象中出现多个对象:

const data = [{
    tasks: [{
        requestTaskId: 'be6ee458-8ef0-11ec-912a-3d12c29b6342',
        price: 5,
    },
    {
        requestTaskId: 'be6ee502-8ef0-11ec-b81a-3d12c29b6342',
        price: 5,
    },
    ],
    request: {
        tasks: [{
            id: 'be6ee458-8ef0-11ec-912a-3d12c29b6342',
            quantity: 10,
        },
        {
            id: 'be6ee502-8ef0-11ec-b81a-3d12c29b6342',
            quantity: 10,
        },
        ],
    },
},];



// function for calculating the total of one object holding tasks and request props.
function calculateTotalPrice(entity) {

    // iterate through all tasks and "reduce" them to one number :)
    return entity.tasks.reduce((total, task) => {

        // Search for a request with the same id!.
        const request = entity.request.tasks.find(request => request.id === task.requestTaskId)

        if (request) {
            return total + (request.quantity * task.price)
        }

        // If no price is found, return current total and log something!.
        console.log('No price found for task:', task)
        return total
    }, 0)
}


// With your object you can now reduce this aswell for getting the grand 
// total over all objects..
const totalPrice = data.reduce((grandTotal, entity) => {
    return grandTotal + calculateTotalPrice(entity)
}, 0)

console.log('totalPrice:', totalPrice)

您可以使用 Array.reduce() 计算所有任务的总价,首先调用输入数组,然后调用任务。

如果没有找到 requestTask 的任务,我们将保留总数不变。如果您觉得这更好地反映了您的用例,您可以更改此行为以抛出错误。

我们将其包装在一个 getTotalSum() 函数中。

let input1 = [ { tasks: [ { requestTaskId: 'be6ee458-8ef0-11ec-912a-3d12c29b6342', price: 5, }, { requestTaskId: 'be6ee502-8ef0-11ec-b81a-3d12c29b6342', price: 5, }, ], request: { tasks: [ { id: 'be6ee458-8ef0-11ec-912a-3d12c29b6342', quantity: 10, }, { id: 'be6ee502-8ef0-11ec-b81a-3d12c29b6342', quantity: 10, }, ], }, }, ];

let input2 = [ { tasks: [ { requestTaskId: '4a0cc1d8-9720-48c4-9678-3372c20ff7c3', price: 10, }, { requestTaskId: '6c178a61-e9aa-45bf-bcde-1a52bcd29205', price: 1, }, ], request: { tasks: [ { id: '4a0cc1d8-9720-48c4-9678-3372c20ff7c3', quantity: 2, }, { id: '6c178a61-e9aa-45bf-bcde-1a52bcd29205', quantity: 3, }, ], }, }, ];

function getTotalSum(input) {
    return input.reduce((total, { tasks, request }) => { 
        return tasks.reduce((total, task) => {
            const requestTask = request.tasks.find(({ id }) => id === task.requestTaskId);
            total += requestTask ? task.price * requestTask.quantity: 0;
            return total;
        }, total)
    }, 0)
}

console.log('Sum1:', getTotalSum(input1))
console.log('Sum2:', getTotalSum(input2))

如果您的对象如图所示排序,每个任务按索引推进相应的请求,那么使用 .map().reduce() 方法将实现您的目标:

const total = orders.map(order => order.tasks.reduce(
    (tot, prod, index) => tot + prod.price * order.request.tasks[index].quantity, 0
));

console.log( total );

演示版

const orders = [{
    tasks: [{
            requestTaskId: 'be6ee458-8ef0-11ec-912a-3d12c29b6342',
            price: 5,
        },
        {
            requestTaskId: 'be6ee502-8ef0-11ec-b81a-3d12c29b6342',
            price: 5,
        },
    ],
    request: {
        tasks: [{
                id: 'be6ee458-8ef0-11ec-912a-3d12c29b6342',
                quantity: 10,
            },
            {
                id: 'be6ee502-8ef0-11ec-b81a-3d12c29b6342',
                quantity: 10,
            },
        ],
    },
},{
    tasks: [{
            requestTaskId: 'dabee458-8ef0-11ec-912a-3d12c29b6342',
            price: 15,
        },
        {
            requestTaskId: 'dabee502-8ef0-11ec-b81a-3d12c29b6342',
            price: 15,
        },
    ],
    request: {
        tasks: [{
                id: 'dabee458-8ef0-11ec-912a-3d12c29b6342',
                quantity: 15,
            },
            {
                id: 'dabee502-8ef0-11ec-b81a-3d12c29b6342',
                quantity: 50,
            },
        ],
    },
}];

const total = orders.map(order => order.tasks.reduce(
    (tot, prod, index) => tot + prod.price * order.request.tasks[index].quantity, 0
));

console.log( total );