JSFiddle - React, Tailwind, and code Playground

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.min.js"></script>

JavaScript

var arr =
[
    { N: 10, Name: "Foo" },
    { N: 10, Name: "Bar" },

    { N: 20, Name: "Foo" },
    { N: 20, Name: "Bar" }
];

var arrComplex =
[
    { N: { Value: 10 }, Name: "Foo" },
    { N: { Value: 10 }, Name: "Bar" },

    { N: { Value: 20 }, Name: "Foo" },
    { N: { Value: 20 }, Name: "Bar" }
];

var eArr = Enumerable.From(arr);
var eArrComplex = Enumerable.From(arrComplex);

var result = eArrComplex.GroupBy("e => e.N"
                                 , "e => e.Name"
                                 , "e, group => { Key: e, Elements: group.ToArray() }"
                                 , "e => e.Value").ToArray();

console.log("linq");
console.log(result);


/* ****************************** */

function GroupByControl(a, keySelector, elementSelector)
{
    if (!elementSelector)
        elementSelector = function(e) { return e; };

    var result = {};
    var key;
    for (var i = 0, n = a.length; i < n; ++i)
    {
        key = keySelector(a[i]);

        result[key] = result[key] || { Key: key, Elements: [] };
        result[key].Elements.push(elementSelector(a[i]));
    }
    var keys = Object.keys(result);
    var ret = [];
    for (var i = 0, n = keys.length; i < n; ++i)
    {
        ret.push(result[keys[i]]);
    }

    return ret;
}

var resultControl = GroupByControl(arr, function(e) { return e.N }, function(e) { return e.Name });

console.log("Custom (flat-only)");
console.log(resultControl);