16

Below is an array in which I have to group 3 values in each object:

var xyz = {"name": ["hi","hello","when","test","then","that","now"]};

Output should be below array:

[["hi","hello","when"],["test","then","that"],["now"]]
2
  • 1
    Do a search for chunk. (NB Lodash has a chunk function) Commented Jun 27, 2016 at 7:59
  • @user14900042 You've added an extra level of indentation with your edit. Commented Dec 28, 2020 at 15:11

8 Answers 8

18

Here's a short and simple solution abusing the fact that .push always returns 1 (and 1 == true):

const arr = [0, 1, 2, 3, 4, 5, 6]
const n = 3

arr.reduce((r, e, i) =>
    (i % n ? r[r.length - 1].push(e) : r.push([e])) && r
, []); // => [[0, 1, 2], [3, 4, 5], [6]]

Plus, this one requires no libraries, in case someone is looking for a one-liner pure-JS solution.

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

2 Comments

It's a clever and very useful solution that can be used as an expression and one can even use it to format currency with thousands separators when reversed and r.push([e]) becomes r.push([',',e]) ;)
Note 0 is a falsy value in JavaScript so this works without a comparison to 0.
16

Pure javascript code:

function groupArr(data, n) {
    const group = [];
    for (let i = 0, j = 0; i < data.length; i++) {
        if (i >= n && i % n === 0)
            j++;
        group[j] = group[j] || [];
        group[j].push(data[i])
    }
    return group;
}

groupArr([1,2,3,4,5,6,7,8,9,10,11,12], 3);

Comments

7

This can be covered by lodash _.chunk:

var xyz = {"name": ["hi","hello","when","test","then","that","now"]},size = 3;
console.log(_.chunk(xyz.name, size));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

1 Comment

For completeness' sake, this also works with Underscore.
4

You may use:

function groupBy(arr, n) {
  var group = [];
  for (var i = 0, end = arr.length / n; i < end; ++i)
    group.push(arr.slice(i * n, (i + 1) * n));
  return group;
}

console.log(groupBy([1, 2, 3, 4, 5, 6, 7, 8], 3));

2 Comments

modifying the array your just iterating over is one of the oldest anti-patterns in programming....
What did you smoke @jebbie? I'm not modifying the array I'm iterating over! If you look closer, you'll see that I create a new array and then I add slices of the array passed in argument. Array.prototype.slice always returns a new array. IT NEVER MODIFIES IT.
3

Hi please refer this https://plnkr.co/edit/3LBcBoM7UP6BZuOiorKe?p=preview. for refrence Split javascript array in chunks using underscore.js

using underscore you can do

JS

 var data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
var n = 3;
var lists = _.groupBy(data, function(element, index){
  return Math.floor(index/n);
});
lists = _.toArray(lists); //Added this to convert the returned object to an array.
console.log(lists);

or

Using the chain wrapper method you can combine the two statements as below:

var data = ["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", "a11", "a12", "a13"];
var n = 3;
var lists = _.chain(data).groupBy(function(element, index){
  return Math.floor(index/n);
}).toArray()
.value();

4 Comments

That's looks like the same answer given to this question (stackoverflow.com/questions/8566667/…)
yeah i made reference also
@gayathri : I want to print that group in following structure . Can you help in that ? <ul> <li><span>a1</span><span>a2</span><span>a3</span></li> <li><span>a4</span><span>a5</span><span>a6</span></li> <li><span>a7</span><span>a8</span><span>a9</span></li> </ul>
Instead of cutting and pasting the answer to the other question it would be more relevant to change it so that it applied to the data structure in this question.
3

Here is another simple oneliner, quite similar to the solution of gtournie.

  1. We create an array of the desired length array.length / n.
  2. We map portions of the initial array to the new array elements.
const group = (array, n) => 
  [...Array(Math.ceil(array.length / n))]
    .map((el, i) => array.slice(i * n, (i + 1) * n));
var xyz = {"name": ["hi","hello","when","test","then","that","now"]};
group(xyz.name, 3)

gives

[["hi","hello","when"],["test","then","that"],["now"]]

Comments

1

Here's a curry-able version that builds off Avare Kodcu's Answer.

function groupBy(groupSize,rtn,item,i)
{
    const j=Math.floor(i/groupSize)

    !rtn[j]?rtn[j]=[item]:
            rtn[j].push(item)

    return rtn
}

arrayOfWords.reduce(curry(groupBy,3),[])

Comments

1

I ran into this same problem and came up with solution using vanilla js and recursion

const groupArr = (arr, size) => {
    let testArr = [];
    const createGroup = (arr, size) => {
        // base case
        if (arr.length <= size) {
            testArr.push(arr);
        } else {
            let group = arr.slice(0, size);
            let remainder = arr.slice(size);
            testArr.push(group);
            createGroup(remainder, size);
        }
    }
    createGroup(arr, size);
    return testArr;
}

let data = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(groupArr(data, 3));
>>> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

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.