Alexey K
Alexey K

Reputation: 6723

How to split array to sub-arrays with similar values?

I have the array ["oop", "poo", "oop", "kkd", "ddd", "kkd"].

Is there any elegant way I can split it to sub-arrays, so each array contains elements with same values?

I want to achieve the following

var arrayOne = ["oop", "oop"]
var arrayTwo = ["poo"]
var arrayThree = ["kkd", "kkd"]
var arrayFour = ["ddd"]

Upvotes: 1

Views: 1317

Answers (4)

shabs
shabs

Reputation: 718

You could maybe do something like this, but the requirement kinda feels like a code smell in the first place.

const mixedArray = ["oop", "poo", "oop", "kkd", "ddd", "kkd"];
const splitArrays = {};

mixedArray.forEach(v => {
  if (!!splitArrays[v]) {
    splitArrays[v].push(v);
  } else {
    splitArrays[v] = [v];
  }
})

console.log(splitArrays);

edit: If functional purity is a concern then ug_'s use of reduce is ipso facto preferable.

Upvotes: 3

ug_
ug_

Reputation: 11440

You could use reduce.

var arr = ["oop", "poo", "oop", "kkd", "ddd", "kkd"];
var mapped = arr.reduce((map, val)=>{
     if(!map[val]) {
         map[val]=[];
     }
     map[val].push(val); 
     return map;
}, {});

You can even get weird and make it a 1 liner, although probably not the brightest idea just in terms of clarity.

arr.reduce((m, v)=>(m[v]=m[v]||[]).push(v) && m, {});

Upvotes: 3

adeneo
adeneo

Reputation: 318182

You could reduce and destructure

var arr = ["oop", "poo", "oop", "kkd", "ddd", "kkd"];
var obj = arr.reduce( (a,b) => (a[b] = a[b] + 1 || 1, a), {});

var [arrayOne, arrayTwo, arrayThree, arrayFour] = Object.keys(obj).map(k=>Array(obj[k]).fill(k));

console.log(arrayOne, arrayTwo, arrayThree, arrayFour);

Upvotes: 1

Daniel Möller
Daniel Möller

Reputation: 86600

You can create a dictionary counting the values:

counter = {}

L = myArray.length
for (var i = 0; i < L; i++)
{
    if (myArray[i] in counter)
    {
        counter[myArray[i]]+=1
    }
    else
    {
        counter[myArray[i]]=1
    }
}

Upvotes: 1

Related Questions