0

I have an array named listSelected which feeds after each selection in another grid.

const listSelected =    
 [{    
    "_id": "10",    
    "age": 35,    
    "name": "Paige Zamora",    
    "gender": "female",    
    "company": "AUTOMON",    
    "**reference_id": "12**"    
  },    
  {    
    "_id": "11",    
    "age": 40,    
    "name": "Jennifer Carr",    
    "gender": "female",    
    "company": "SYNKGEN",    
    "**reference_id": "11**"    
  }];  

I would like to check that for each value reference_id one checks in another table named data if this value exists, we get the value id in a new array, even if the value reference_id is present several times.

const data = [{    
    "_id": "**10**",    
    "age": 35,    
    "name": "Paige Zamora",    
    "gender": "female",    
    "company": "AUTOMON",    
    "**reference_id": "12**"    
  },    
  {    
    "_id": "**11**",    
    "age": 40,    
    "name": "Jennifer Carr",    
    "gender": "female",    
    "company": "SYNKGEN",    
    "**reference_id": "11**"    
  },    
  {    
    "_id": "**12**",    
    "age": 38,    
    "name": "Weaver Rosales",    
    "gender": "male",    
    "company": "ETERNIS",    
    "**reference_id": "12**"    
  },    
  {
    "_id": "13",    
    "age": 31,    
    "name": "Myers Pickett",    
    "gender": "male",    
    "company": "ETERNIS",    
    "reference_id": "13"    
  },    
  {    
    "_id": "14",    
    "age": 36,    
    "name": "Dona Nicholson",    
    "gender": "female",    
    "company": "ETERNIS",    
    "reference_id": "14"    
  },    
  {
    "_id": "15",    
    "age": 21,    
    "name": "Niki Blur",    
    "gender": "female",    
    "company": "AUTOMON",    
    "reference_id": "15"    
  },    
  {    
    "_id": "16",    
    "age": 37,    
    "name": "Bod Dennart",    
    "gender": "male",    
    "company": "SYNKGEN",    
    "reference_id": "16"    
  },    
  {    
    "_id": "17",    
    "age": 26,    
    "name": "Richard Nelson",    
    "gender": "male",    
    "company": "ETERNIS",    
    "reference_id": "17"    
  },    
  {    
    "_id": "**12**",    
    "age": 45,    
    "name": "Pedro Kluivert",    
    "gender": "female",    
    "company": "SYNKGEN",    
    "**reference_id": "18**"    
  }    
];

In the end the new grid will give the following data:

const newGrid = [11,12]

I was thinking of using two nested forEach functions, like these :

const newGrid = [];

listSelected.forEach((elt) => {
  data.forEach((item) => {
    if (item.reference_id === elt.reference_id) {
       newGrid.push(item.id);
       newGrid = Array.from(new Set(newGrid));
     }
   });
});

Is there not a simpler way to simplify this function to avoid using nested forEach ?

Harun Yilmaz
  • 8,281
  • 3
  • 24
  • 35
Greg-A
  • 772
  • 1
  • 19
  • 41
  • Your question is totally unclear. Please at least provide the end result, so that we know what to aim for. –  Feb 04 '19 at 12:39
  • The final result is indicated in the post. **newGrid = [11,12]** – Greg-A Feb 04 '19 at 12:40
  • It is the data array ? Because in your nested loops, you seem to use it ... –  Feb 04 '19 at 12:41
  • Oh so just a count ? –  Feb 04 '19 at 12:41
  • Must we absolutely use two forEach ? – Greg-A Feb 04 '19 at 12:43
  • No, as stated in several answers, you can use other operators on your arrays. I also have posted a solution implying a single loop in the code, to avoid nested loops (be warned that `indexOf` still makes two loops, it's just your code that looks "cleaner") –  Feb 04 '19 at 13:17

3 Answers3

3

You could make a "reverse-unique" array :

const listSelected = [
  { "_id": "10", "age": 35, "name": "Paige Zamora", "gender": "female", "company": "AUTOMON", "reference_id": "12" }, 
  { "_id": "11", "age": 40, "name": "Jennifer Carr", "gender": "female", "company": "SYNKGEN", "reference_id": "11" }
];

const data = [
  { "_id": "10", "age": 35, "name": "Paige Zamora", "gender": "female", "company": "AUTOMON", "reference_id": "12" }, 
  { "_id": "11", "age": 40, "name": "Jennifer Carr", "gender": "female", "company": "SYNKGEN", "reference_id": "11" }, 
  { "_id": "12", "age": 38, "name": "Weaver Rosales", "gender": "male", "company": "ETERNIS", "reference_id": "12" }, 
  { "_id": "13", "age": 31, "name": "Myers Pickett", "gender": "male", "company": "ETERNIS", "reference_id": "13" }, 
  { "_id": "14", "age": 36, "name": "Dona Nicholson", "gender": "female", "company": "ETERNIS", "reference_id": "14" }, 
  { "_id": "15", "age": 21, "name": "Niki Blur", "gender": "female", "company": "AUTOMON", "reference_id": "15" }, 
  { "_id": "16", "age": 37, "name": "Bod Dennart", "gender": "male", "company": "SYNKGEN", "reference_id": "16" }, 
  { "_id": "17", "age": 26, "name": "Richard Nelson", "gender": "male", "company": "ETERNIS", "reference_id": "17" }, 
  { "_id": "12", "age": 45, "name": "Pedro Kluivert", "gender": "female", "company": "SYNKGEN", "reference_id": "18" }
];

const merged = [
  ...listSelected.map(item => item.reference_id),
  ...data.map(item => item.reference_id)
];

const reverseUnique = merged.filter((item, index, array) => array.indexOf(item) === index && array.lastIndexOf(item) !== index);

console.log(reverseUnique);

This only makes one loop, instead of every other method doing two nested (because yes, filter/find/some do a loop over the array)

You start by concatenating the two arrays in a single one, and using only the reference ID.

Then, you use the opposite of a unique filtering function.

  • so you are saying others are using two nested loops! what do you think the runtime of array.indexof() method? – Md Golam Rahman Tushar Feb 04 '19 at 13:18
  • 1
    @GolamRahmanTushar maybe you should check the comments on the question. –  Feb 04 '19 at 13:19
  • so you think, instead of using find method inside forEach, first merging the arrays and then writing a single for loop with two nested forloops inside it, is much more clean? – Md Golam Rahman Tushar Feb 04 '19 at 13:24
  • 1
    Where did I say that ? I provided a solution implying a single loop (understand, "not nested functions") instead of two nested functions. But if you ask me what is the cleanest, then `reduce` would be. Maybe you should stop talking to me, you seem to have an issue with my self and you don't actually criticize the answer, but rather my personal opinions. –  Feb 04 '19 at 13:27
  • I think you criticized other's answer and devoted them saying your answer is better without stating any valid reasoning. stop doing this. and this is my last comment. – Md Golam Rahman Tushar Feb 04 '19 at 13:37
  • @GolamRahmanTushar never said my answer was better. You did about yours though. Sure, bye. –  Feb 04 '19 at 13:37
-1

You can use the find method of array like following:

newGrid = [];

listSelected.forEach((elt) => {

    newGrid.push(data.find(function check(item) {

        return item.reference_id === elt.reference_id;

    }).reference_id);
});
Md Golam Rahman Tushar
  • 2,175
  • 1
  • 14
  • 29
-1
const newGrig = listSeleced.map(listItem => {
    if (data.some(dataItem => dataItem.item.reference_id === listItem.item.reference_id) {
        return listItem.reference_id;
    }
    return;
});

Have not tested this, but it should work. You could also do something similar with reduce.

Sandra Willford
  • 3,459
  • 11
  • 49
  • 96