首页 > 解决方案 > Retrieve and group by object element in JS (JSON)

问题描述

I've got a file versions.json:

{
    "components":{
    "toto": {
        "artifacts": [
        {
            "name": "test-toto",
            "type": "html"
        },
        {
            "name": "test-tata",
            "type": "html"
        }
        ]
    },
    "titi": {
        "test": [
        {
            "name": "test-titi",
            "type": "html"
        }
        ]
    }
    "versions": {
    "test-toto": "2.1",
    "test-tata": "2.2",
    "test-titi": "2.3"
    }

I've got a file versions2.json:

{
    "components":{
    "toto": {
        "artifacts": [
        {
            "name": "test-toto",
            "type": "html"
        },
        {
            "name": "test-tata",
            "type": "html"
        }
        ]
    },
    "titi": {
        "test": [
        {
            "name": "test-titi",
            "type": "html"
        }
        ]
    }
    "versions": {
    "test-toto": "1.0",
    "test-tata": "1.1",
    "test-titi": "1.3"
    }

I want to push only the versions (bigger and smaller versions) where the version is different with their name of component

Expected:

[{
    components: "toto",
    newVersion: "2.2",   // bigger version (here test-tata) 
    oldVersion: "1.0"    // smaller version (here toto-tata)
},
{
    components: "titi",
    newVersion: "2.3",
    oldVersion: "1.3",
}
]

Actual Result:

[{
    components: "toto",
    newVersion: "2.1", 
    oldVersion: "1.0"    
},
{
    components: "toto",
    newVersion: "2.2", 
    oldVersion: "1.1"    
},
{
    components: "titi",
    newVersion: "2.3",
    oldVersion: "1.3",
}
]

My script :

public async listDiffer(): Promise<any[]> {
        const showVersion = fs.readFileSync("versions.json", "utf8");
        const json1 = JSON.parse(showVersion);
        const list1 = json1.versions;
        const components = json1.components;

        const showVersion2 = fs.readFileSync("versions2.json", "utf8");
        const json2 = JSON.parse(showVersion2);
        const list2 = json2.versions;

        const diffList: Array<{ components: string; newVersion: string; oldVersion: string }> = [];

        const keysFromHead = Object.keys(list1);
        const keysFromHeadComponents = Object.keys(components);

        keysFromHeadComponents.forEach((element) => {
            components[element].artifacts.map((arti) => {
                keysFromHead.forEach((key) => {
                    if (list1[key] !== list2[key] && key === arti.name) {
                        diffList.push({
                            components: element,
                            newVersion: list1[key],
                            oldVersion: list2[key],
                        });
                    }
                });
            });
        });

        console.log(diffList);
        return diffList;
    }

So what I want it's if they are multiple element in same components, I just need to retrieve the smaller and bigger version (like toto example)

Thanks in advance for your help

标签: javascripttypescript

解决方案


通过假设components在对象的第一级,您可以将两个对象都放在一个对象中并创建一个用于收集版本的对象。然后将值作为结果。

const
    version1 = { components: { toto: { artifacts: [{ name: "test-toto", type: "html" }, { name: "test-tata", type: "html" }] }, titi: { test: [{ name: "test-titi", type: "html" }] } }, versions: { "test-toto": "2.1", "test-tata": "2.2", "test-titi": "2.3" } },
    version2 = { components: { toto: { artifacts: [{ name: "test-toto", type: "html" }, { name: "test-tata", type: "html" }] }, titi: { test: [{ name: "test-titi", type: "html" }] } }, versions: { "test-toto": "1.0", "test-tata": "1.1", "test-titi": "1.3" } },
    result = Object.values([version1, version2].reduce((r, { components, versions }) => {
        Object.keys(components).forEach(components => {
            const version = versions['test-' + components];
            if (!r[components]) {
                r[components] = { components, oldVersion: version, newVersion: version };
                return;
            }
            if (version.localeCompare(r[components].oldVersion, undefined, { numeric: true, sensitivity: 'base' }) < 0) {
                r[components].oldVersion = version;
            }
            if (version.localeCompare(r[components].newVersion, undefined, { numeric: true, sensitivity: 'base' }) > 0) {
                r[components].newVersion = version;
            }
        });
        return r;
    }, {}));

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


推荐阅读