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.