Reputation: 59
I have two large files containing object arrays, the first containing data like this:
[{
"id": "001",
"word": "abbess",
"def": "(noun) The lady superior of a nunnery",
}, {
"id": "002"
"word": "abbey",
"def": "(noun) The group of buildings which collectively form the dwelling-place of a society of monks or nuns.",
}, (etc...)
The second, data like this:
[{
"meta": {
"term": "abbess",
"part_of_speech": "noun",
"definition": "The lady superior of a nunnery"
}
}, {
"meta": {
"term": "abbey",
"part_of_speech": "noun",
"definition": "The group of buildings which collectively form the dwelling-place of a society of monks or nuns"
}
}, (etc...)
I want to combine these two files so the "meta" information from the second file is added to the corresponding information from the first file, so:
[{
"id": "001",
"word": "abbess",
"def": "(noun) The lady superior of a nunnery",
"meta": {
"term": "abbess",
"part_of_speech": "noun",
"definition": "The lady superior of a nunnery"
}
}, {
"id": "002"
"word": "abbey - (noun) The group of buildings which collectively form the dwelling-place of a society of monks or nuns.",
"def": "(noun) The group of buildings which collectively form the dwelling-place of a society of monks or nuns.",
"meta": {
"term": "abbey",
"part_of_speech": "noun",
"definition": "The group of buildings which collectively form the dwelling-place of a society of monks or nuns"
}
}, (etc...)
Right now, I'm have this code
var newArr = [];
for(var i = 0; i < meta.length; i++) {
newArr.push(words[i]);
newArr.push(meta[i]);
}
that adds the meta objects after the words object, not within. Do I need to loop down another layer to add the meta objects within the words objects, or is there a different method that would work better here, like .concat()?
Upvotes: 3
Views: 56
Reputation: 33726
An alternative is using the function reduce
+ function map
The function reduce
converts the second array input2
to an object where keys are coming from the attribute meta.term
, this way the function map
uses that object to find very fast the corresponding meta values by key rather than a repeated find
execution.
This approach works independently of the order because will match the attributes word
and attributes meta.term
.
const input1 = [{ "id": "001", "word": "abbess", "def": "(noun) The lady superior of a nunnery",}, { "id": "002", "word": "abbey", "def": "(noun) The group of buildings which collectively form the dwelling-place of a society of monks or nuns.",}],
input2 = [{ "meta": { "term": "abbess", "part_of_speech": "noun", "definition": "The lady superior of a nunnery" }}, { "meta": { "term": "abbey", "part_of_speech": "noun", "definition": "The group of buildings which collectively form the dwelling-place of a society of monks or nuns" }}],
mapped = input2.reduce((a, o) => Object.assign(a, {[o.meta.term]: o.meta}), {}),
result = input1.map((o) => Object.assign({}, o, {meta: mapped[o.word]}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 40444
In case the arrays doesn't line up, you can use .map
and .find
to achieve your goal.
const input1 = [{
"id": "001",
"word": "abbess",
"def": "(noun) The lady superior of a nunnery",
}, {
"id": "002",
"word": "abbey",
"def": "(noun) The group of buildings which collectively form the dwelling-place of a society of monks or nuns.",
}];
const input2 = [{
"meta": {
"term": "abbess",
"part_of_speech": "noun",
"definition": "The lady superior of a nunnery"
}
}, {
"meta": {
"term": "abbey",
"part_of_speech": "noun",
"definition": "The group of buildings which collectively form the dwelling-place of a society of monks or nuns"
}
}];
const output = input1.map(item => {
return {
...item,
...input2.find(item2 => item2.meta.term === item.word)
}
});
console.log(output);
Upvotes: 1
Reputation: 371059
If each element in each array corresponds to the other element with the same index in the other array, then it's a simple .map
, which is more appropriate than a for
loop:
const input1 = [{
"id": "001",
"word": "abbess",
"def": "(noun) The lady superior of a nunnery",
}, {
"id": "002",
"word": "abbey",
"def": "(noun) The group of buildings which collectively form the dwelling-place of a society of monks or nuns.",
}];
const input2 = [{
"meta": {
"term": "abbess",
"part_of_speech": "noun",
"definition": "The lady superior of a nunnery"
}
}, {
"meta": {
"term": "abbey",
"part_of_speech": "noun",
"definition": "The group of buildings which collectively form the dwelling-place of a society of monks or nuns"
}
}];
const combined = input1.map((item) => {
const { word } = item ;
const foundInput2 = input2.find(({ meta: { term }}) => term === word);
const { meta } = foundInput2;
return { ...item, meta };
});
console.log(combined);
Upvotes: 2
Reputation: 3483
Just set the new property of the object from the first array.
var newArr = [];
for(var i = 0; i < meta.length; i++) {
var word = words[i];
word.meta = meta[i].meta;
newArr.push(word);
}
This is assuming that both arrays will always have info of the same word in the same order.
Bonus tip - if you are using ECMAScript 6, you could concatenate the objects like this:
const newArr = [];
for(let i = 0; i < meta.length; i++) {
newArr.push({ ...words[i], ...meta[i]} );
}
Upvotes: 0
Reputation: 17654
loop through the array of metas and use Object.assign to add the meta to the corresponding object in the first array :
var arr = [{
"id": "001",
"word": "abbess",
"def": "(noun) The lady superior of a nunnery",
}, {
"id": "002",
"word": "abbey",
"def": "(noun) The group of buildings which collectively form the dwelling-place of a society of monks or nuns.",
}]
const arr2 = [{
"meta": {
"term": "abbess",
"part_of_speech": "noun",
"definition": "The lady superior of a nunnery"
}
}, {
"meta": {
"term": "abbey",
"part_of_speech": "noun",
"definition": "The group of buildings which collectively form the dwelling-place of a society of monks or nuns"
}
}]
arr2.forEach((e, i) => {
Object.assign(arr[i], e);
});
console.log(arr)
Upvotes: 2