• 简易node ts代码给json进行sort或者diff


    compare工具的问题在于,如果这些json的节点是未排序,导致基本上显示全部不同。
    node上几行代码,可以输出两个json的不同之处,也可以输出一个所有属性节点有序的json。

    注意:这里数组元素也会以对象形式显现,数组的keys即为数组元素index。因为如果按数组处理,需要处理数组的元素是对象的情况,如果数组的元素是对象,那么排序规则是什么?(或者数组应该原样显示?,那么如果是字符串数组,难道不排序下?)
    所以没有太完美的解决办法,反正我们的目的是比对和查找,不用于生产,那么代码统一处理带来的简洁可以弥补这点瑕疵。

    tsconfig.json

    {
      "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "strict": true,
        "strictFunctionTypes": true,
        "strictPropertyInitialization": true,
        "strictNullChecks": true,
        "allowJs": true,
        "checkJs": true,
        "removeComments": true,
        "noImplicitAny": true,
        "noImplicitThis": true,
        "noImplicitReturns": true,
        "noImplicitOverride": true,
        "sourceMap": true,
        "declaration": true,
        "rootDir":"./src",
        "outDir":"./out",
        "experimentalDecorators": true,
        "watch":true
      },
      "include":[
        "./src/**/*"
      ],
      "exclude":[
    //    "./src/test/*"
      ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    package.json

    {
      "name": "json-sort-diff",
      "version": "1.0.0",
      "scripts": {
        "build": "tsc --build tsconfig.json"
      },
      "dependencies": {
        "@types/node": "^18.11.9"
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    json-sort-diff.ts

    const fs = require('fs');
    
    (function main() {
        const argv = process.argv;
        // argv[0] ==> node
        // argv[1] ==> the js file
    
        if (argv.length == 3) {
            const json = fs.readFileSync(argv[2]);
            const obj = JSON.parse(json);
            console.log(JSON.stringify(orderedJson(obj), null, 2));
        } else if (argv.length === 4) {
            const fromJson = fs.readFileSync(argv[2]);
            const toJson = fs.readFileSync(argv[3]);
            const from = JSON.parse(fromJson);
            const to = JSON.parse(toJson);
            diff(from, to);
        } else {
            console.log("Examples:");
            console.log("1. Dump sorted json: node json-sort-diff.js path-of-json");
            console.log("2. Diff two json: node json-sort-diff.js path-of-from-json path-of-to-json")
            process.exit(0);
        }
    })();
    
    function orderedJson(unordered: any): any {
        return Object.keys(unordered).sort().reduce((obj: any, key: string) => {
            const value = unordered[key];
            if (typeof value === 'object') {
                obj[key] = orderedJson(value)
            } else {
                obj[key] = unordered[key];
            }
            return obj;
        }, {});
    }
    
    function dump(obj: any) {
        walk(obj, '', (path, key, value, leaf) => {
            if (leaf) {
                console.log(`${path} -> #(${value})`);
            } else {
                console.log(path);
            }
        });
    }
    
    function diff(from: any, to: any) {
        const noFounds: string[] = [];
        const diffInfos: DiffInfo[] = [];
        walk(from, '', (path, key, value, leaf) => {
            const segments = path.split('/');
            if (segments[0] === '') {
                segments.shift();
            }
            let current = to;
            for (const segment of segments) {
                if (current[segment] === undefined) {
                    noFounds.push(path);
                }
                current = current[segment];
            }
            if (leaf) {
                if (current !== value) {
                    diffInfos.push({ path, from: value, to: current })
                }
            }
        });
        console.log('\x1b[33m%s\x1b[0m', 'List of not found:');
        for (const noFound of noFounds.sort()) {
            console.log(noFound);
        }
        console.log('\x1b[33m%s\x1b[0m', 'List of different value:');
        for (const diffInfo of diffInfos.sort((a, b) => a.path.localeCompare(b.path))) {
            console.log(`${diffInfo.path} diff -> from:${diffInfo.from}; to:${diffInfo.to}`);
        }
    }
    
    export function walk(object: any, path: string, callback: (path: string, key: string, value: any, leaf: boolean) => void) {
        for (const [key, value] of Object.entries(object)) {
            const current = path + '/' + key;
            if (typeof value === 'object') {
                callback(current, key, value, false);
                walk(value, current, callback);
            } else {
                callback(current, key, value, true);
            }
        }
    }
    
    interface DiffInfo {
        path: string;
        from: any;
        to: any;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
  • 相关阅读:
    C++11 智能指针 已完成未发布
    Python Web开发记录 Day9:Django part3 用户管理
    Django之模版层
    性能调优流程规范、成熟度划分、团队建设
    【51】分布式计算:如果所有人的大脑都联网会怎样?
    智慧煤矿/智慧矿区视频汇聚存储与安全风险智能分析平台建设思路
    Hyperreal number
    STM32F10x SPL V3.6.2 集成 FreeRTOS v202112
    SGP.22-V.3.1-安全2
    Vision Transformer(Vit)
  • 原文地址:https://blog.csdn.net/kslinabc/article/details/127971689