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?






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






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

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)