繁体   English   中英

对嵌套的对象数组进行分组

[英]Group nested array of objects

我有以下 object:

const attributes = [
    {
        id: "a",
        values: [
            {
                value: [
                    {
                        _id: "aa",
                        value: "1500"
                    },
                    {
                        _id: "ab",
                        value: "580"
                    }
                ]
            },
            {
                value: [
                    {
                        _id: "aa",
                        value: "400"
                    }
                ]
            }
        ]
    },
    {
        id: "a",
        values: [
            {
                value: [
                    {
                        _id: "aa",
                        value: "420"
                    },
                    {
                        _id: "ab",
                        value: "300"
                    }
                ]
            },
            {
                value: [
                    {
                        _id: "aa",
                        value: "480"
                    },
                    {
                        _id: "ab",
                        value: "1000"
                    }
                ]
            },
            {
                value: [
                    {
                        _id: "aa",
                        value: "880"
                    },
                    {
                        _id: "ab",
                        value: "740"
                    }
                ]
            }
        ]
    },
    {
        id: "b",
        values: [
            {
                value: [
                    {
                        _id: "ba",
                        value: "1500"
                    },
                    {
                        _id: "bb",
                        value: "580"
                    }
                ]
            },
            {
                value: [
                    {
                        _id: "ba",
                        value: "400"
                    }
                ]
            }
        ]
    },
];

我想根据属性id和值_id对数据进行分组,因此我可以得到以下 object 作为回报:

[
    {
        id: "a",
        values: [
            {
                value: [
                    {
                        _id: "aa",
                        values: ["1900", "1780"]
                    },
                    {
                        _id: "ab",
                        values: ["580", "2040"]
                    }
                ]
            }
        ]
    },
    {
        id: "b",
        values: [
            {
                value: [
                    {
                        _id: "ba",
                        values: ["1900"]
                    },
                    {
                        _id: "bb",
                        values: "[580"]
                    }
                ]
            },
        ]
    },
];

如果结果没有意义,我可以解释更多。 无论如何,我尝试通过执行以下操作来尝试结果,但它没有按预期工作,我确信有一种更简洁的方法可以做到这一点。

let newAttributes = [];
attributes.forEach(attribute => {
    let currentAttribute = { id: attribute.id, values: attribute.values[0] };
    attribute.values.shift();
    attribute.values.forEach(attributeValues => {
        attributeValues.value.forEach(vl => {
            var values = currentAttribute.values.value.find(vl2 => vl2._id === vl._id);
            if (values && attribute.id === currentAttribute.id) {
                if (!values.values) {
                    values.values = [];
                }
                values.values.push(vl.value);
            }
        });
    });
    newAttributes.push(attributes);
});

newAttributes.forEach(attribute => {
    attribute.values.value.forEach(vl => {
        if (vl.values) {
            vl.values.push(vl.value);
        } else {
            vl.values = [vl.value]
        }
        delete vl.value;
    });
    attribute.values.value.forEach(vl => {
        vl.values = vl.values.reduce((a, b) => {
            return Number(a) + Number(b);
        }, 0);
         vl.values =  [vl.values.toString()]
    });
});

console.log(newAttributes);

编辑:

说明:让我们以属性id = 'a'和值_id = 'aa'为例:

对于id = 'a'的第一个属性,我们有两个_id = 'aa'值,一个是1500 ,另一个是400 ,我们将这两个值相加得到1900 ,然后我们有另一个id = 'a'的属性id = 'a'具有 3 个值_id = 'aa' ,值为420480880 ,这些值的总和为1780 ,我们将该总和推入id = 'a'的第一个属性_id = 'aa'的值中id = 'a'

 const attributes = [ { id: "a", values: [ { value: [ { _id: "aa", value: "1500" }, { _id: "ab", value: "580" } ] }, { value: [ { _id: "aa", value: "400" } ] } ] }, { id: "a", values: [ { value: [ { _id: "aa", value: "420" }, { _id: "ab", value: "300" } ] }, { value: [ { _id: "aa", value: "480" }, { _id: "ab", value: "1000" } ] }, { value: [ { _id: "aa", value: "880" }, { _id: "ab", value: "740" } ] } ] }, { id: "b", values: [ { value: [ { _id: "ba", value: "1500" }, { _id: "bb", value: "580" } ] }, { value: [ { _id: "ba", value: "400" } ] } ] }, ]; let newStructure = attributes.map(attr => { let tempValues = {}; attr.values.forEach((value, index)=> { value.value.forEach((v)=>{ if(typeof tempValues[v._id] == "undefined") tempValues[v._id] = 0; tempValues[v._id] += +v.value }) }) return { id: attr.id, values: tempValues } }).reduce((accumulator, currentValue)=>{ if(typeof accumulator[currentValue.id] == "undefined") accumulator[currentValue.id] = { id: currentValue.id, values: {} }; Object.keys(currentValue.values).forEach( valueKey =>{ if(typeof accumulator[currentValue.id].values[valueKey] == "undefined") accumulator[currentValue.id].values[valueKey] = [currentValue.values[valueKey]]; else accumulator[currentValue.id].values[valueKey].push(currentValue.values[valueKey]); }) return accumulator },{}) newStructure = Object.keys(newStructure).map(itemKey => { return { id: itemKey, values: { value: Object.keys(newStructure[itemKey].values).map(valueKey => { return { _id: valueKey, value: newStructure[itemKey].values[valueKey] } }) } } }); console.log(newStructure)

使用更直接/原生的 javascript object forms,我能够使大多数部分更加离散。 此代码通常假定 object 可能没有给定索引的初始值,因此不会根据您似乎具有的attribute.values[0]初始化和未来假设仅使用这些索引来执行任何优化.

let newAttributes = {}; // will be converted back
for (attribute of attributes){

    let newValues = []; // turn it into [ { "aa":1500, "ab":580 }, {"aa":400} ]
    for (valueSet of attribute.values){
        let newObj = {};
        for (value of valueSet.value){
            newObj[value._id] = Number(value.value);
        }
        newValues.push(newObj);
    }

    let sum = {};
    for (value of newValues){
        for (id in value){
            if (!(id in sum)) sum[id] = 0;
            sum[id] += value[id];
        }
    }

    if ( !(attribute.id in newAttributes))
        newAttributes[attribute.id] = {};

    outAttrib = newAttributes[attribute.id]
    for (id in sum){
        if ( !(id in outAttrib)) outAttrib[id] = [];
        outAttrib[id].push(sum[id].toString());
    }

}
// at this point, the object would be in, imo, more manageable form
// a: { aa: [ '1900', '1780' ], ab: [ '580', '2040' ] },
// b: { ba: [ '1900' ], bb: [ '580' ] }

let out = [];
for (id in newAttributes){ // can be integrated into former loop but I think this makes more sense
    let value = [];
    for (_id in newAttributes[id]){
        value.push({_id: _id, values: newAttributes[id][_id]});
    }
    out.push({id: id, values: [ { value: value } ] });
}
console.log(out);

我从头开始编写代码,它的工作

 const attributes = [ { id: "a", values: [ { value: [ { _id: "aa", value: "1500" }, { _id: "ab", value: "580" } ] }, { value: [ { _id: "aa", value: "400" } ] } ] }, { id: "a", values: [ { value: [ { _id: "aa", value: "420" }, { _id: "ab", value: "300" } ] }, { value: [ { _id: "aa", value: "480" }, { _id: "ab", value: "1000" } ] }, { value: [ { _id: "aa", value: "880" }, { _id: "ab", value: "740" } ] } ] }, { id: "b", values: [ { value: [ { _id: "ba", value: "1500" }, { _id: "bb", value: "580" } ] }, { value: [ { _id: "ba", value: "400" } ] } ] }, ]; newAttributes = []; attributes.forEach(attribute => { childOutput = childNode(attribute.values) var isIdPresent = newAttributes.filter(e => { return e.id == attribute.id }); if (isIdPresent.length > 0) { var parentNode = isIdPresent[0] newAttributes = newAttributes.filter(e => { return e.id.= attribute;id }). parentNode["values"][0].value = (mergeChildNode(parentNode["values"][0],value. childOutput)) newAttributes.push(parentNode) } else { var parentNode ={} parentNode["id"] = attribute:id parentNode["values"] = [{value.[]}] parentNode["values"][0].value = (mergeChildNode(parentNode["values"][0],value. childOutput)) newAttributes;push(parentNode) } }). console.log(JSON;stringify(newAttributes)). function childNode(attrValues){ childOutput = {} attrValues.forEach(valueArray => { valueArray.value.forEach(valueObj => { if (childOutput.hasOwnProperty(valueObj._id)) { childOutput[valueObj._id] = childOutput[valueObj._id] + parseInt(valueObj.value) } else { childOutput[valueObj._id] = parseInt(valueObj;value) } }); }), return childOutput } function mergeChildNode (inputArray. childOutput) { for (const property in childOutput) { var isIdPresent = inputArray.filter(e => { return e;_id == property }). if (isIdPresent;length > 0) { var newObj = isIdPresent[0]. inputArray = inputArray.filter(e => { return e;_id.= property }). newObj["values"].push(childOutput[property]) inputArray:push(newObj) } else { inputArray,push({ _id: property, values: [childOutput[property]] }) } } return inputArray }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM