如何在JavaScript中连接两个对象数组?

时间:2018-09-16 12:28:58

标签: javascript inner-join

在JavaScript中联接数据的最佳方法是什么?是否有类似的库Pandas中的Python还是迭代方式?我有两个带有不同对象的数组。列表orders包含有关订单的一般信息,列表ordersPayed包含有关订单是否已付款+金额等的信息。

const orders = [
{
    orderId: 1,
    orderDate: '2018-01-01',
    orderAmount: 100
},
{
    orderId: 2,
    orderDate: '2018-02-01',
    orderAmount: 100
},
{
    orderId: 3,
    orderDate: '2018-03-01',
    orderAmount: 100
},
{
    orderId: 4,
    orderDate: '2018-03-01',
    orderAmount: 100
}];
    
const ordersPayed = [
{
    orderId: 1,
    payedAmount: 90,
    debitorName: 'abc'
},
{
    orderId: 3,
    payedAmount: 80,
    debitorName: 'abc'
},
{
    orderId: 6,
    payedAmount: 90,
    debitorName: 'abc'
}];

let newOrderList = [];
    
for (i = 0; i < orders.length; i++) {
    for (j = 0; j < ordersPayed.length; j++) {
        if (orders[i].orderId == ordersPayed[j].orderId) {
            newOrderList.push(orders[i].orderId);
            newOrderList.push(orders[i].orderDate);
            newOrderList.push(orders[i].orderAmount);
            newOrderList.push(ordersPayed[j].payedAmount);
            newOrderList.push(ordersPayed[j].debitorName);
        }
        else if (j == (ordersPayed.length-1)) {
            newOrderList.push(orders[i].orderId);
            newOrderList.push(orders[i].orderDate);
            newOrderList.push(orders[i].orderAmount);
            newOrderList.push('not_payed_yet');
            newOrderList.push('not_known_yet');
        }
    }
}
    
console.log(newOrderList);

通过键orderId完成匹配。最后,我想创建一个包含所有订单和相应信息的新列表,无论它们是否已经付款。

上面的代码是我要采用的方法,但是由于性能原因以及是否存在更多陷阱,我不知道这是否很好。所以我想到了一个匹配的库或类似的库。

不幸的是,这不能100%正确地工作。结果应如下所示:

[{
    orderId: 1,
    orderDate: '2018-01-01',
    orderAmount: 100,
    payedAmount: 90
},
{
    orderId: 2,
    orderDate: '2018-02-01',
    orderAmount: 100,
    payedAmount: 'not_payed_yet'
},
{
    orderId: 3,
    orderDate: '2018-03-01',
    orderAmount: 100,
    payedAmount: 80
},
{
    orderId: 4,
    orderDate: '2018-03-01',
    orderAmount: 100,
    payedAmount: 'not_payed_yet'
}]

有人提示吗?

5 个答案:

答案 0 :(得分:5)

const newOrderList = orders.map((order, index) => {
   let payedOrder = ordersPayed.find(o => o.orderId === order.orderId);
   return Object.assign({}, order, payedOrder)
});

答案 1 :(得分:2)

您可以尝试以下解决方案:

// Returns an array with order objects, which contain all information
let newOrderList = orders.map((order, index) => {
    let payedOrder = ordersPayed.find(o => o.orderId === order.orderId);

    // Returns a new object to not manipulate the original one
    return {
        orderId: order.orderId,
        orderDate: order.orderDate, 
        orderAmount: order.orderAmount, 
        payedAmount: payedOrder ? payedOrder.payedAmount : 'not_payed_yet', 
        debitorName: payedOrder ? payedOrder.debitorName: 'not_known_yet'
    }
});

答案 2 :(得分:2)

使用lodash和ES6箭头表示法,解决方案可能会变得很短:

.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
REGEXP

答案 3 :(得分:1)

对于您的问题,我将minmanx-reduce: 148.5929143627707 default min + max: 3.376458476185718 # ouch .. seems we just use these minmax1passOptimized: 15.975109436292087 minmax1pass: 20.29275910515082 Array.reduce一起使用:

Array.find

答案 4 :(得分:1)

您的代码中有一个小错误。 else if不会按照您想要的方式工作,因为每当最后一次匹配失败时,您总是将not found条目推入新数组。您可以尝试使用此调整后的代码版本:

const orders = [
{
    orderId: 1,
    orderDate: '2018-01-01',
    orderAmount: 100
},
{
    orderId: 2,
    orderDate: '2018-02-01',
    orderAmount: 100
},
{
    orderId: 3,
    orderDate: '2018-03-01',
    orderAmount: 100
},
{
    orderId: 4,
    orderDate: '2018-03-01',
    orderAmount: 100
}];
    
const ordersPayed = [
{
    orderId: 1,
    payedAmount: 90,
    debitorName: 'abc'
},
{
    orderId: 3,
    payedAmount: 80,
    debitorName: 'abc'
},
{
    orderId: 6,
    payedAmount: 90,
    debitorName: 'abc'
}];

let newOrderList = [];
    
for (i = 0; i < orders.length; i++) {
    let payed = false;
    for (j = 0; j < ordersPayed.length; j++) {
        if (orders[i].orderId == ordersPayed[j].orderId) {
            newOrderList.push({ orderId: orders[i].orderId,
                                orderDate: orders[i].orderDate,
                                orderAmount: orders[i].orderAmount,
                                payedAmount: ordersPayed[j].payedAmount,
                                debitorName: ordersPayed[j].debitorName });
            payed = true;
        }
    }
    if (!payed) {
        newOrderList.push({ orderId: orders[i].orderId,
                            orderDate: orders[i].orderDate,
                            orderAmount: orders[i].orderAmount,
                            payedAmount: 'not_payed_yet',
                            debitorName: 'not_known_yet' });
    }
}
    
console.log(newOrderList);

但是请记住,只有在数据集之间具有1:1关系时,这才起作用。这意味着如果您在ordersPayed中可以有多个条目,而在orders中可以有多个条目,那么结果也将为这些订单有多个条目。