How can I join two arrays of objects in JavaScript?
How can I join two arrays of objects in JavaScript?
What is the best way to join data in JavaScript? Are there libraries like e.g. Pandas
in Python
or is iteration the way to go? I have two arrays with different objects inside. The list orders
contains information about orders in general and the list ordersPayed
contains the information whether an order was already payed + the amount etc.
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);
The matching is done by the key orderId
. At the end I want to have a new list with all orders + the corresponding info whether they were already payed or not.
orderId
The code above is my approach to go, but I don't know if this is good for performance reasons and whether there are more pitfalls. So I thought of a matching library or something similar.
Unfortunately this doesn't work 100% correctly. The result should look something like this:
[
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'
]
Anybody got any tips?
asking for llibrary is ot. please add the wanted result as well, beside the problem you are facing.
– Nina Scholz
Sep 16 '18 at 12:33
Possible duplicate of Inner join two objects javascript
– Hasan Fathi
Sep 16 '18 at 13:01
5 Answers
5
const newOrderList = orders.map((order, index) =>
let payedOrder = ordersPayed.find(o => o.orderId === order.orderId);
return Object.assign(, order, payedOrder)
);
You can try following solution:
// 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'
);
Using lodash and ES6 arrow notation the solution can become quite short:
// 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>
For your problem, I would use the Array.reduce
with Array.find
:
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,
,
];
, );
There is a small error in you code. The else if
there is not going to work the way you want, because you will always push a not found
entry to the new array, whenever the last match fails. You could try this adjusted version of your code:
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);
But keep in mind that this is only going to work if you have a 1:1
relationship between the datasets. Meaning if you can have multiple entries in ordersPayed
for an entry in orders
, the result is also going to have multiple entries for those orders.
1:1
ordersPayed
orders
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy
Where is the data from? If it is from a database, you could solve this with a simple join on the server side.
– Jenny O'Reilly
Sep 16 '18 at 12:33