2

I couldn't find an answer to this specific question on S.O.

Let's say I have an array of strings, or in this case, numbers:

var x = [1, 1, 1, 2, 3, 3, 5, 3, 3, 5, 4, 5];

I'd like the output to be:

var output = [[1,1,1], [2], [3,3,3,3,3], [4], [5, 5, 5]];

I was hoping to use Lodash but most of that stuff tends to remove duplicates rather chunk them together into their own array. Maybe some kind of .map iterator?

The order of the output doesn't really matter so much. It just needs to chunk the duplicates into separate arrays that I'd like to keep.

3
  • so you want to group them ? Commented May 24, 2019 at 16:10
  • an array of strings? this is an array of integers the way you typed it. Commented May 24, 2019 at 16:11
  • 1
    If you're using lodash anyway, grouper = _.flow([_.groupBy, _.values]) would be the function you're looking for. Commented May 24, 2019 at 16:56

5 Answers 5

5

You can use reduce to group the array elements into an object. Use Object.values to convert the object into an array.

var x = [1, 1, 1, 2, 3, 3, 5, 3, 3, 5, 4, 5];
var result = Object.values(x.reduce((c, v) => {
  (c[v] = c[v] || []).push(v);
  return c;
}, {}));

console.log(result);

Shorter version:

var x = [1, 1, 1, 2, 3, 3, 5, 3, 3, 5, 4, 5];
var result = Object.values(x.reduce((c, v) => ((c[v] = c[v] || []).push(v), c), {}));

console.log(result);

Sign up to request clarification or add additional context in comments.

2 Comments

Aren't they starting with a flat array and trying to get a not-flat array?
OMG. Hahahah. I need more coffee
1

You can do this with Array.reduce in a concise way like this:

var x = [1, 1, 1, 2, 3, 3, 5, 3, 3, 5, 4, 5]

let result = x.reduce((r,c) => (r[c] = [...(r[c] || []), c],r), {})

console.log(Object.values(result))

The exact same with lodash would be:

var x = [1, 1, 1, 2, 3, 3, 5, 3, 3, 5, 4, 5]

let result = _.values(_.groupBy(x))

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Using _.values to extract the values of the grouping object and _.groupBy to get the actual groupings

Comments

0

Use Array#prototype#reduce to group them:

const x = [1, 1, 1, 2, 3, 3, 5, 3, 3, 5, 4, 5];

let helperObj = {};
const res = x.reduce((acc, curr) => {

  // If key is not present then add it
  if (!helperObj[curr]) {
    helperObj[curr] = curr;
    acc.push([curr]);
  }

  // Else find the index and push it
  else {
    let index = acc.findIndex(x => x[0] === curr);

    if (index !== -1) {
      acc[index].push(curr);
    }
  }
  return acc;
}, []);

console.log(res);

Comments

0

Since you're hoping to use Lodash, you might be interested in groupBy. It returns on object, but the _.values will give you the nested array:

var x = [1, 1, 1, 2, 3, 3, 5, 3, 3, 5, 4, 5];
let groups = _.values(_.groupBy(x))
console.log(groups)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Comments

0

Here's an imperative solution:

var x = [1, 1, 1, 2, 3, 3, 5, 3, 3, 5, 4, 5];

x.sort();

var res = [];

for (const [i, n] of x.entries()) {
  if (n !== x[i-1]) res.push([n]);
  else res[res.length-1].push(n);
}

console.log(res);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.