JS: Reduce array to nested objects

后端 未结 2 1594
你的背包
你的背包 2021-01-21 23:46

So I have this array

var mapped = [[2016, \"October\", \"Monday\", {object}], [2017, \"January\", \"Friday\", {object}], [2017, \"January\", \"Wednesday\", {obje         


        
2条回答
  •  佛祖请我去吃肉
    2021-01-22 00:20

    Not exactly what you specified, but I feel the following script outputs a format that will be most useful -- it only produces arrays at the deepest level:

    const  mapped = [[2016, "October", "Monday", { a: 1 }], [2017, "January", "Friday", { a: 1 }], [2017, "January", "Wednesday", { a: 1 }], [2017, "October", "Monday", { a: 1 }]];
       
    const result = mapped.reduce( (acc, [year, month, day, object]) => {
        let curr = acc[year] = acc[year] || {};
        curr = curr[month] = curr[month] || {};
        curr = curr[day] = curr[day] || [];
        curr.push(object);
        return acc;
    }, {});
    
    console.log(result);
       
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    With array wrapping

    If you really need the wrapping arrays, you can apply an extra recursive function to the previous result:

    const  mapped = [[2016, "October", "Monday", { a: 1 }], [2017, "January", "Friday", { a: 1 }], [2017, "January", "Wednesday", { a: 1 }], [2017, "October", "Monday", { a: 1 }]];
       
    const result = mapped.reduce( (acc, [year, month, day, object]) => {
        let curr = acc[year] = acc[year] || {};
        curr = curr[month] = curr[month] || {};
        curr = curr[day] = curr[day] || [];
        curr.push(object);
        return acc;
    }, {});
    
    function wrapInArrays(data) {
        return Array.isArray(data) ? data 
            : Object.entries(data).map ( ([key, value]) => {
                return { [key]: wrapInArrays(value) };
            });
    }
    
    const wrapped = wrapInArrays(result);
    console.log(wrapped);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

提交回复
热议问题