Alex Morrison
Alex Morrison

Reputation: 186

Split array into arrays of matching values

I have an array of values similar to:

["100", "330", "22", "100", "4.7", "0.01", "0.01", "330", "0.01", "100", "47", "22", "100", "0.01"]

Using JavaScript I would like to split this array into a number of arrays where only matching strings are in those arrays like this:

["100", "100", "100"]
["330", "330"]
["22", "22"]
["0.01", "0.01", "0.01", "0.01"]
["47"]
["4.7"]

Any help with this would be much appreciated! Thanks!

Upvotes: 2

Views: 2056

Answers (5)

Nina Scholz
Nina Scholz

Reputation: 386560

You could collect with a Map and get the values as result.

From inside out:

  • Use Array#reduce with data and use a Map instance as initialValue.
  • As callback take Map#set and collect the values for each group.

Further methods:

  • spread syntax ... for getting all items of an iterable together with

  • logical OR || for having a default value for spreading.

  • Get the values from the map and use it as parameter for

  • Array.from. This generates an array of all values.

var data = ["100", "330", "22", "100", "4.7", "0.01", "0.01", "330", "0.01", "100", "47", "22", "100", "0.01"],
    result = Array.from(data
        .reduce((m, v) => m.set(v, [...m.get(v) || [], v]), new Map)
        .values()
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 3

Siva Kondapi Venkata
Siva Kondapi Venkata

Reputation: 11001

Use reduce method and Object.values

   //Go thru each value in `arr` array and convert into object with 
   //keys as unique (value in array) and values array of value repetitions.


   {
     "100": ["100", "100"],
     "22": ["22"],
     ...
     ...    
   }

   //Use the Object.values to get the Values as array of arrays

const arr = ["100", "330", "22", "100", "4.7", "0.01", "0.01", 
             "330", "0.01", "100", "47", "22", "100","0.01"];

const updated = Object.values(
  arr.reduce(
    (acc, curr) => (
      (acc[curr] = curr in acc ? [...acc[curr], curr] : [curr]), acc
    ),
    {}
  )
);

console.log(updated);

Upvotes: 3

LukStorms
LukStorms

Reputation: 29647

Here's another take on using reduce to group by the values.

It reduces to an object, which is then transformed to an array of arrays.

let valueArray = ["100", "330", "22", "100", "4.7", "0.01", "0.01", "330", "0.01", "100", "47", "22", "100", "0.01"];

let groupedByValue = Object.values(valueArray
  .reduce((acc, x)=>{
   	  let arr = acc[x] || [];
   	  arr.push(x);
   	  acc[x] = arr;
   	  return acc;
   },{}));
 
console.log(groupedByValue);

Extra

Here's a version that will group the unique values by the same format.
It was something cooked up when this question was originally completely misunderstood by yours truly. (it happens...)

let valueArray = ["100", "330", "22", "102", "4.7", "0.01", "0.02", "330", "0.01", "101", "47", "23", "100", "0.02"];

let groupedByFormat = Object.values(valueArray
  .reduce((acc, x)=>{
   	  let val = x.trim();
   	  let format = val.replace(/\d/g,'0');
   	  let arr = acc[format] || [];
   	  if(!arr.includes(val)) {
   		arr.push(val);
   		acc[format] = arr.sort();
   	}
   	return acc;
   },{}));
 
console.log(groupedByFormat);

Upvotes: 1

igg
igg

Reputation: 2250

Here's an example of what you want using Set.

const data = ["100", "330", "22", "100", "4.7", "0.01", "0.01", "330", "0.01", "100", "47", "22", "100", "0.01"];

const unique = new Set(data);
for(let num of unique) {
  console.log(data.filter(d => d == num));
}

Upvotes: -1

M.Dmitriy
M.Dmitriy

Reputation: 1

Also it can be done like this:

const {log} = console;
const arr = ["100", "330", "22", "100", "4.7", "0.01", "0.01", "330", "0.01", "100", "47", "22", "100", "0.01"];
log([...new Set(arr)].map( x => arr.filter( y => y === x )));

Upvotes: -1

Related Questions