I have two JSON files: JSON A has some company properties and the company_id, while JSON B has company names and company ids.
JSON A example:
[
{
"order_name": "Foo",
"company_id": "112233"
},
{
"order_name": "Bar",
"company_id": "123456"
}
]
JSONB example:
[
{
"company_id":"112233",
"name":"ACME company",
},
{
"company_id":"123456",
"name":"John Doe Inc.",
}
]
Which is the most efficient way to do a join by the company_id
values? I would like to have the JSON C (merged result) with the company names correctly added, like this:
[
{
"order_name": "Foo",
"company_id": "123456",
"company_name": "John Doe Inc."
},
{
"order_name": "Bar",
"company_id": "112233",
"company_name": "ACME company"
}
]
Is looping and filter for each the only solution? Is there a more efficient way to do this from a performance point of view?
More info:
- JSON is not sorted by company_id.
- Array A could have more than one object with the same
company_id
- I'm using Javascript (in a Vue.js app), I don't need to support old browsers
CodePudding user response:
I hope this will work for you. Let me know if you have any questions.
const arrayOne = [
{
"order_name": "Foo",
"company_id": "112233"
},
{
"order_name": "Bar",
"company_id": "123456"
}
];
const arrayTwo = [
{
"company_id":"112233",
"name":"ACME company",
},
{
"company_id":"123456",
"name":"John Doe Inc.",
}
];
const [source, target] = arrayOne.length > arrayTwo.length
? [arrayOne, arrayTwo]
: [arrayTwo, arrayOne];
const merged = source.map(object =>
{
// Assuming that in the 2nd array, the match is only found 1 time and it EXISTS.
const matched = target.find(element => element.company_id === object.company_id);
// Merge both objects together
return {
...object,
...matched
};
});
console.log(merged);
CodePudding user response:
By having JSONs:
const jsonA = [
{
"order_name": "Foo",
"company_id": "112233"
},
{
"order_name": "Bar",
"company_id": "123456"
}
];
const jsonB = [
{
"company_id":"112233",
"name":"ACME company",
},
{
"company_id":"123456",
"name":"John Doe Inc.",
}
];
you can merge maps into 3rd map with something like this:
const transform = (data, current={}) =>
data.reduce((prev, company) => {
if(!prev[company['company_id']]) prev[company['company_id']] = {};
prev[company['company_id']] = {...prev[company['company_id']], ...company}
return prev;
}, current);
let jsonMap = transform(jsonA, {});
jsonMap = transform(jsonB, jsonMap);
let jsonC = Object.keys(jsonMap).map(companyId => jsonMap[companyId] );
console.log(jsonC);
CodePudding user response:
In common modern JavaScript, you can do this as you mentioned with higher-order functions like map
, filter
, and so on:
const arrayA = [
{
"order_name": "Foo",
"company_id": "112233"
},
{
"order_name": "Bar",
"company_id": "123456"
}
]
const arrayB = [
{
"company_id":"112233",
"name":"ACME company",
},
{
"company_id":"123456",
"name":"John Doe Inc.",
}
]
const mergeAB = arrayA.map( companyA => {
const matched = arrayB.find(companyB => companyB.company_id === companyA.company_id)
if(matched) {
return {...companyA, ...matched}
} else {
// return companyA element or customize it with your case
}
}
)
console.log(mergeAB)
Note 1: Array.find()
method complexity is O(n) and Array.map()
method complexity is O(n)
Note 2: efficiency is an important thing but not in all situations. sometimes you need to do these types of iteration one time or for a small array size, so no need to worry about the performance.
Note 3: you could compare the answer and find out your best solution since we don't know about your whole code and application.