0

I have 2 array of objects
The first one called data:

const data = [
  {
    id: 1,
    nombre: 'Piero',
  },
  {
    id: 4,
    nombre: 'Nelson',
  },
  {
    id: 7,
    nombre: 'Diego'
  },
 ]

and the second called subs:

const subs = [
  {
    id: 1,
    name: 'Temprano',
  },
  {
    id: 4,
    name: 'A tiempo',
  },
  {
    id: 7,
    name: 'Tarde'
  },
]

In which I want to compare that if they have the same ID, the subs array will pass its name value to it and if it does not match that it puts a '-' in the data array, try this way:

data.forEach((d)=>{
 subs.forEach((s)=>{
   if(d.id === s.id){
     d.subname = s.name;
   }
   else {
     d.subname = '-';
    }
   });
 }); 

But always assign the values with '-' as if it does not match any. What part am I doing wrong? Is there any other simpler way to do this? I would greatly appreciate your help.

The size of the subs array may vary.

AndrewL64
  • 15,794
  • 8
  • 47
  • 79
Piero Pajares
  • 276
  • 1
  • 4
  • 21

3 Answers3

5

It looks like you are not exiting the inner loop when a successful match is found.

In the first example where you are looking for a match for Piero, in your first iteration 1===1 and d.subname is correctly set to 'Temprano'. However, you then continue to compare the values- 1 !== 4 so Temprano is overwritten with '-', and 1 !== 7 so it is overwritten again.

An alternate approach:

data.forEach(d => {
const match = subs.find(s => s.id === d.id);
d.subname = match ? match.name : '-';});

I'd also recommend adding a case where you're not expecting to find a match, so you can see that it works in both cases!

ItsPronounced
  • 5,475
  • 13
  • 47
  • 86
Finn
  • 876
  • 6
  • 6
1

https://codepen.io/anon/pen/MGGBLP?editors=0010

const data = [
  {
    id: 1,
    nombre: 'Piero',
  },
  {
    id: 4,
    nombre: 'Nelson',
  },
  {
    id: 7,
    nombre: 'Diego'
  },
 ];

const subs = [
  {
    id: 1,
    name: 'Temprano',
  },
  {
    id: 4,
    name: 'A tiempo',
  },
  {
    id: 7,
    name: 'Tarde'
  },
];

// by caching one of the arrays in an object, it reduces the run time to linear.
const obj = subs.reduce((acc, item) => {
  acc[item.id] = item;
  return acc;
})

data.forEach(d => {
  if (d.id in obj) {
    d.subname = obj[d.id].name;
  } else {
    d.subname = '-';
  }
});

console.log(data);
Geuis
  • 41,122
  • 56
  • 157
  • 219
1

You just need two lines for this:

var findIds = id => subs.find(findId => findId.id === id);
data.forEach(findId => Object.assign(findId, findIds(findId.id)));

Your data array object should now include the name property from it's respective id sharing object in subs array.


jsFiddle: https://jsfiddle.net/AndrewL64/9k1d3oj2/1/

AndrewL64
  • 15,794
  • 8
  • 47
  • 79