在JavaScript

时间:2018-06-08 08:52:51

标签: javascript json

我正在尝试为我的JSON获得某种结构,但我在这个过程中苦苦挣扎并获得无限循环。

我设法通过使用reduce()方法与原始文件达到某一点,但我坚持最后一步。

这里是JSON

{
    "someNumbers_like_15269": {
        "someNumbers_like_35896": [{
            "TestPoint": "A",
            "ItemNo": "12110",
            "TestDesc": "Penalty Points"
        }, {
            "TestPoint": "A",
            "ItemNo": "12110",
            "TestDesc": "Brix"
        }, {
            "TestPoint": "B",
            "ItemNo": "12110",
            "TestDesc": "Texture"
        }, {
            "TestPoint": "B",
            "ItemNo": "12110",
            "TestDesc": "Viscosity"
        }, {
            "TestPoint": "C",
            "ItemNo": "12110",
            "TestDesc": "PH"
        }, {
            "TestPoint": "C",
            "ItemNo": "12110",
            "TestDesc": "Taste"
        }]
    }
}

所需的结果

{
"someNumbers_like_15269": {
    "someNumbers_like_35896": {
        "ItemNo": "12110",
        "someOtherThing": "blabla",
        "Test": [{
            "TestPoint": "A",
            "TestDesc": ["Penalty Points", "Brix"]
        }, {
            "TestPoint": "B",
            "TestDesc": ["Texture", "Viscosity"]
        }, {
            "TestPoint": "C",
            "TestDesc": ["PH", "Taste"]
        }]
    }
}

} 的 PS: 将有多个CC 多个批次,JSON超过8.5万行

**

我的原始尝试可以在here

中找到

**

2 个答案:

答案 0 :(得分:3)

使用Array.reduceArray.forEachObject.valuesObject.entries



var data = {"someNumbers_like_15269":{"someNumbers_like_35896":[{"TestPoint":"A","ItemNo":"12110","TestDesc":"Penalty Points"},{"TestPoint":"A","ItemNo":"12110","TestDesc":"Brix"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Texture"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Viscosity"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"PH"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"Taste"}],"someNumbers_like_21":[{"TestPoint":"A","ItemNo":"12110","TestDesc":"Penalty Points"},{"TestPoint":"A","ItemNo":"12110","TestDesc":"Brix"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Texture"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Viscosity"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"PH"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"Taste"}]},"someNumbers_like_15270":{"someNumbers_like_35800":[{"TestPoint":"A","ItemNo":"12110","TestDesc":"Penalty Points"},{"TestPoint":"A","ItemNo":"12110","TestDesc":"Brix"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Texture"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Viscosity"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"PH"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"Taste"}]}};

// Iterate for all first level values
Object.values(data).forEach(v => {
  // Iterate for all second level values
  Object.entries(v).forEach(([k,v1]) => {
    // Set the updated value back in object
    v[k] = Object.values(v1.reduce((a,{TestDesc, TestPoint, ...rest}) => {
      a[TestPoint] ? a[TestPoint].TestDesc.push(TestDesc) : a[TestPoint] = {TestPoint, ...rest, TestDesc : [TestDesc]};
      return a;
      }, {}));
  });
})

console.log(data);




修改



var data = {"someNumbers_like_15269":{"someNumbers_like_35896":[{"TestPoint":"A","ItemNo":"12110","TestDesc":"Penalty Points"},{"TestPoint":"A","ItemNo":"12110","TestDesc":"Brix"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Texture"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Viscosity"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"PH"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"Taste"}],"someNumbers_like_21":[{"TestPoint":"A","ItemNo":"12110","TestDesc":"Penalty Points"},{"TestPoint":"A","ItemNo":"12110","TestDesc":"Brix"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Texture"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Viscosity"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"PH"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"Taste"}]},"someNumbers_like_15270":{"someNumbers_like_35800":[{"TestPoint":"A","ItemNo":"12110","TestDesc":"Penalty Points"},{"TestPoint":"A","ItemNo":"12110","TestDesc":"Brix"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Texture"},{"TestPoint":"B","ItemNo":"12110","TestDesc":"Viscosity"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"PH"},{"TestPoint":"C","ItemNo":"12110","TestDesc":"Taste"}]}};

// Iterate for all first level values
Object.values(data).forEach(v => {
  // Iterate for all second level values
  Object.entries(v).forEach(([k,v1]) => {
    let {TestDesc, TestPoint, ...rest} = v1[0];
    let Test = Object.values(v1.reduce((a,{TestDesc, TestPoint}) => {
      a[TestPoint] ? a[TestPoint].TestDesc.push(TestDesc) : a[TestPoint] = {TestPoint, TestDesc : [TestDesc]};
      return a;
    }, {}));
    v[k] = {...rest, Test};
  });
})

console.log(data);




答案 1 :(得分:3)

获取原始数据并尊重任何嵌套对象和数组,您可以采用嵌套方法并给出分组的关键和值。

Array.isArray(w) ...的部分可以用硬编码的属性检查替换,或者如果所有的键都有一个用于分组的数组,则只删除。

外部对象的键和值,由kv表示,内部键和v的值,由lw表示,其中所有对象都被破坏并使用这种模式重建:

Object.assign(...Object
    .entries(object)
    .map(([key, value]) => ({ [key]: value })
)

在此示例中,对于下一个级别,value中的({ [key]: value })将替换为嵌套对象的另一个相同结构。

最后,如果找到所需的分组键,则reduce会占用,并在累加器中查找对象。如果没有,它会生成一个新对象,然后将分组值推送到数组中以收集此项目。

var data = { CC1: { Batch1: [{ TestPoint: "A", ItemNo: "12110", TestDesc: "Penalty Points" }, { TestPoint: "A", ItemNo: "12110", TestDesc: "Brix" }, { TestPoint: "B", ItemNo: "12110", TestDesc: "Texture" }, { TestPoint: "B", ItemNo: "12110", TestDesc: "Viscosity" }, { TestPoint: "C", ItemNo: "12110", TestDesc: "PH" }, { TestPoint: "C", ItemNo: "12110", TestDesc: "Taste" }] } },
    group = { key: 'TestPoint', value: 'TestDesc' },
    result = Object.assign(...Object.entries(data).map(([k, v]) => ({
        [k]: Object.assign(...Object.entries(v).map(([l, w]) => ({
            [l]: Array.isArray(w)
                ? w.reduce((r, o) => {
                    var item = r.find(p => o[group.key] === p[group.key]);
                    if (!item) {
                        r.push(item = Object.assign({}, o, { [group.value]: [] }));
                    }
                    item[group.value].push(o[group.value]);
                    return r;
                }, [])
                : w
        })))
    })));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

最后是嵌套对象的完整动态递归方法。如果找到数组,则进行分组。

此代码可防止分组值的重复条目。

function groupBy(object, by) {
    return Array.isArray(object)
        ? object.reduce((r, o) => {
            var item = r.find(({ [by.key]: v }) => o[by.key] === v);
            if (!item) {
                item = Object.assign({}, o, { [by.value]: [] });
                r.push(item);
            }
            if (!item[by.value].includes(o[by.value])) {
                item[by.value].push(o[by.value]);
            }
            return r;
        }, [])
        : Object.assign(...Object
            .entries(object)
            .map(([key, value]) => ({ [key]: groupBy(value, by) }))
        );
}

var data = { CC1: { Batch1: [{ TestPoint: "A", ItemNo: "12110", TestDesc: "Penalty Points" }, { TestPoint: "A", ItemNo: "12110", TestDesc: "Brix" }, { TestPoint: "B", ItemNo: "12110", TestDesc: "Texture" }, { TestPoint: "B", ItemNo: "12110", TestDesc: "Viscosity" }, { TestPoint: "C", ItemNo: "12110", TestDesc: "PH" }, { TestPoint: "C", ItemNo: "12110", TestDesc: "Taste" }] } },
    result = groupBy(data, { key: 'TestPoint', value: 'TestDesc' });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }