create nested objects in javascript like groupby in C#

后端 未结 2 1322
感动是毒
感动是毒 2021-02-10 01:25
IList Customers =
            flat.GroupBy(cust => new { cust.ReferenceNumber, cust.Name, cust.Address })
                .Select(c => new Customer         


        
2条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-10 02:00

    Even though this is an old question, I thought I'd offer a more elegant solution:

    /**
     * Groups an array of objects by one or more keys
     * 
     * @param array arr       The array of objects to group
     * 
     * @param string|function A string representing the child property to group by
     *                        or a function that returns an array of one or more properties.
     * 
     * @returns               An object with keys representing the grouping properties, 
     *                        finally holding an array of records that fell into 
     *                        those groups.
     */
    var group = function( items, by ) {
        var groups = {},
            group,
            values,
            i = items.length,
            j,
            key,
            group_keys;
    
        // make sure we specified how we want it grouped
        if( !by ) { return items; }
        while( i-- ) { 
    
            // find out group values for this item
            values = ( typeof(by) === "function" && by( items[i] ) || 
                       typeof items[i] === "object" && items[i][by] || 
                       items[i] );
    
            // make sure our group values are an array
            values = values instanceof Array && values || [ values ];
    
            // recursively group
            group = groups;
            for( j = 0; j < values.length; j++ ) {
                key = values[j];
                group = ( group [key] || ( group [key] = j === values.length - 1 && [] || {} ) );
            }
    
            // for the last group, push the actual item onto the array
            group = ( group instanceof Array && group || [] ).push( items[i] );
        }
    
        return groups;
    };
    

    Calling it with this:

    var items = [
        { "id" : 1, "name" : "foo",  "category" : "a" },
        { "id" : 2, "name" : "foo",  "category" : "a" },
        { "id" : 3, "name" : "bar",  "category" : "b" },
        { "id" : 4, "name" : "free", "category" : "a" },
        { "id" : 5, "name" : "beer", "category" : "b" },
        { "id" : 6, "name" : "foo",  "category" : "b" }
    ];
    
    var groups = group( items, function( item ) { return [ item.category, item.name ]; } );
    

    Yields this:

    {
        b: {
            foo: [
                {
                    id: 6
                    name: foo
                    category: b
                }
            ]
            beer: [
                {
                    id: 5
                    name: beer
                    category: b
                }
            ]
            bar: [
                {
                    id: 3
                    name: bar
                    category: b
                }
            ]
        }
        a: {
            free: [
                {
                    id: 4
                    name: free
                    category: a
                }
            ]
            foo: [
                {
                    id: 2
                    name: foo
                    category: a
                }
                {
                    id: 1
                    name: foo
                    category: a
                }
            ]
        }
    }
    

    Anyway, hope this helps someone.

提交回复
热议问题