![](/img/trans.png)
[英]How can I left join two javascript objects of arrays using properties as primary keys?
[英]How can I join two arrays of objects in JavaScript?
在JavaScript中联接数据的最佳方法是什么? 是否有Python
类的库(例如Pandas
)或迭代方式? 我有两个带有不同对象的数组。 列表orders
包含有关常规orders
信息,列表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'
}]
有人有提示吗?
const newOrderList = orders.map((order, index) => {
let payedOrder = ordersPayed.find(o => o.orderId === order.orderId);
return Object.assign({}, order, payedOrder)
});
您可以尝试以下解决方案:
// 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'
}
});
使用lodash和ES6箭头表示法,解决方案可能会变得很短:
// Array of Javascript Objects 1: 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 } ]; // Array of Javascript Objects 2: const ordersPayed = [{ orderId: 1, payedAmount: 90, debitorName: 'abc' }, { orderId: 3, payedAmount: 80, debitorName: 'abc' }, { orderId: 6, payedAmount: 90, debitorName: 'abc' } ]; var merged = _.merge(_.keyBy(orders, 'orderId'), _.keyBy(ordersPayed, 'orderId')); const newArr = _.map(merged, o => _.assign({ "payedAmount": "not_payed_yet", "debitorName": "not_known_yet" }, o)); var result = _.values(newArr); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
对于您的问题,我将Array.reduce
与Array.find
:
const newOrderList = orders.reduce((acc, order) => {
const { orderId } = order;
const orderPayed = ordersPayed.find((orderPayed) => orderPayed.orderId === orderId);
if (orderPayed) {
return [
...acc,
{
...order,
...orderPayed,
}
];
}
return [
...acc,
{
...order,
},
];
}, []);
您的代码中有一个小错误。 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
,结果也将具有这些订单的多个条目。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.