Home > Enterprise >  How to use a JS reduce to return ana rray without duplicates when using also .split
How to use a JS reduce to return ana rray without duplicates when using also .split

Time:05-31

I would like to understand how to return from a .reduce array of items that contain no duplicates.

The array I have is particular:

['JJ2AG-001099', 'JJ2AG-001999', 'JJ3AG-001999', 'JJ4AG-001999']

In details, the string inside the array is formed by 2 identifiers as example

  • JJ2AG -> this identifies to which group of people that person is related
  • 001099 -> this identifies the id of that person

So what I need initially is to split the elements of the array without having the - so the result will be as follows:

[0: JJ2AG, 1: 001099]

Then I should check from the newArry if the 0 of every item is unique and as a result, I should have just an array:

['JJ2AG', 'JJ3AG', 'JJ4AG']

So this last array contains only once the 0 part of every item as described above

I tried to use reduce but cannot figure out how to have this new array and I cannot use loops as for and forEach as per the requirements I have so what I have done so far in the snippet but I have no idea how to create a new array as I need as

['JJ2AG', 'JJ3AG', 'JJ4AG']

const ids = ['JJ2AG-001099', 'JJ2AG-001999', 'JJ3AG-001999', 'JJ4AG-001999'];

const x = ids.reduce(( acc, item) => {
  console.log('ACC', acc);
  console.log('ITEM', item);
  
  const splited = item.split('-');
  console.log(splited);
  
  const groupId = splited[0];
  console.log(groupId);
  
  return acc.includes(groupId) ? [splited] : [...acc, item];
}, []);

console.log(x)

CodePudding user response:

Since it seems you're on modern JavaScript, you can actually use Set for this:

const ids = ['JJ2AG-001099', 'JJ2AG-001999', 'JJ3AG-001999', 'JJ4AG-001999'];

const x = [...new Set(ids.map(id => id.split("-")[0]))]

console.log(x)

Set takes unique elements from an array, so first, map all of the ids to the first part in the string (id.split("-")[0]), turn it into a set, and using spread, turn it back into an array.

CodePudding user response:

Just change:

return acc.includes(groupId) ? [splited] : [...acc, item];

To:

return acc.includes(groupId) ? acc : [...acc, groupId];

Whenever a duplicate is found, you're basically doing away with previous unique IDs and instead return the duplicate with [groupId]; you should instead return the unique IDs unchanged. You also have to append to the array of unique Ids groupId not item. See the demo below:

const ids = ['JJ2AG-001099', 'JJ2AG-001999', 'JJ3AG-001999', 'JJ4AG-001999'];

const x = ids.reduce(( acc, item) => {
  //console.log('ACC', acc);
  //console.log('ITEM', item);
  
  const splited = item.split('-');
  //console.log(splited);
  
  const groupId = splited[0];
  //console.log(groupId);
  
  return acc.includes(groupId) ? acc : [...acc, groupId];
}, []);

console.log(x)

WHICH YOU CAN ALSO WRITE AS ...

const ids = ['JJ2AG-001099', 'JJ2AG-001999', 'JJ3AG-001999', 'JJ4AG-001999'];

const x = ids.reduce(
    ( acc, item) => 
    acc.includes(item.split('-')[0]) ? acc : [...acc, item.split('-')[0]]
    , []
);

console.log(x);

CodePudding user response:

You can use a Set or you can use a plain object and add keys as needed. This is a oneliner that uses reduce.

Object.keys(ids.reduce((acc, current)=> { acc[current.split("-")[0]]=true; return acc}, {}))

What this does is that it adds keys to the object, if you encounter an existing key it doesn't matter. In the end you need the keys of the accumulator and that's where Object.keys comes into play.

  • Related