R Christian
R Christian

Reputation: 59

Add object contents in one object array within objects in another array

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

Answers (5)

Ele
Ele

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

Marcos Casagrande
Marcos Casagrande

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

CertainPerformance
CertainPerformance

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

Mark E
Mark E

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

Taki
Taki

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

Related Questions