@compare-json/core(JavaScript)
@compare-json/core 是一个轻量、零依赖的 JavaScript/TypeScript 库,用于深度对比 JSON 值——也是本网站使用的对比引擎。它可以检测两个 JSON 结构之间的新增、删除、类型变更和值变更,并支持细粒度的对比行为控制。
语言:JavaScript/TypeScript —— 通过 npm 分发。其它语言的实现可能会陆续推出。
安装
# npm
npm install @compare-json/core
# yarn
yarn add @compare-json/core
# pnpm
pnpm add @compare-json/core
快速开始
import { compareJSON } from '@compare-json/core';
const baseJSON = { name: 'Alice', age: 30, hobbies: ['reading'] };
const contrastJSON = { name: 'Bob', age: '30', hobbies: ['reading', 'coding'], email: '[email protected]' };
const differences = compareJSON({ baseJSON, contrastJSON });
console.log(differences);
// [
// { pathSegments: ['name'], pathString: 'name', pathBelongsTo: 'both', diffType: 'valueChanged' },
// { pathSegments: ['age'], pathString: 'age', pathBelongsTo: 'both', diffType: 'typeChanged' },
// { pathSegments: ['hobbies', '[1]'], pathString: 'hobbies[1]', pathBelongsTo: 'contrast', diffType: 'added' },
// { pathSegments: ['email'], pathString: 'email', pathBelongsTo: 'contrast', diffType: 'added' },
// ]
对比选项
import { compareJSON } from '@compare-json/core';
// 将数字字符串视为与数字相等
compareJSON({
baseJSON: { count: 1 },
contrastJSON: { count: '1' },
options: { numericStringEqualsNumber: true },
});
// [](无差异)
// 键名大小写不敏感
compareJSON({
baseJSON: { Name: 'Alice' },
contrastJSON: { name: 'Alice' },
options: { keyCaseInsensitive: true },
});
// [](无差异)
// 值大小写不敏感
compareJSON({
baseJSON: { status: 'OK' },
contrastJSON: { status: 'ok' },
options: { valueCaseInsensitive: true },
});
// [](无差异)
各选项的详细说明请参阅对比选项。
数组对比方法
import { compareJSON } from '@compare-json/core';
// 'byIndex'(默认)—— 按相同索引逐一对比
compareJSON({ baseJSON: [1, 2, 3], contrastJSON: [2, 3, 4] });
// 'lcs' —— 使用最长公共子序列算法,得到最小差异
compareJSON({
baseJSON: [1, 2, 3],
contrastJSON: [2, 3, 4],
options: { arrayCompareMethod: 'lcs' },
});
// 'unordered' —— 将数组视为多重集合,忽略元素顺序
compareJSON({
baseJSON: [1, 2, 3],
contrastJSON: [3, 2, 1],
options: { arrayCompareMethod: 'unordered' },
});
// [](无差异)
每种策略的深入讲解请参阅数组对比方法。
格式化路径
import { pathSegmentsToString } from '@compare-json/core';
pathSegmentsToString(['users', '[0]', 'name']);
// 'users[0].name'
API 参考
compareJSON
function compareJSON(params: {
baseJSON: unknown;
contrastJSON: unknown;
options?: CompareOptions;
}): JSONValueDifference[];
深度对比两个 JSON 值,返回差异数组。两个值相等时返回空数组。
| 参数 | 类型 | 说明 |
|---|---|---|
baseJSON | unknown | 基准 JSON 值(视为原始一侧)。 |
contrastJSON | unknown | 与基准对比的 JSON 值。 |
options | CompareOptions | 可选的对比行为设置。 |
pathSegmentsToString
function pathSegmentsToString(pathSegments: string[]): string;
将路径片段数组(即 JSONValueDifference.pathSegments)转换为可读的点表示法字符串。数组索引片段(如 '[0]')不带前导点直接拼接;对象键用 . 连接。
pathSegmentsToString([]); // ''
pathSegmentsToString(['user', 'name']); // 'user.name'
pathSegmentsToString(['items', '[2]', 'id']); // 'items[2].id'
CompareOptions
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
arrayCompareMethod | ArrayCompareMethod | 'byIndex' | 数组的对比策略。 |
keyCaseInsensitive | boolean | false | 为 true 时,对象键按大小写不敏感方式对比。 |
valueCaseInsensitive | boolean | false | 为 true 时,字符串值按大小写不敏感方式对比。 |
numericStringEqualsNumber | boolean | false | 为 true 时,数字字符串视为与对应数字相等(如 "1" 等于 1)。 |
ArrayCompareMethod
type ArrayCompareMethod = 'byIndex' | 'lcs' | 'unordered';
| 值 | 说明 |
|---|---|
'byIndex' | 按相同索引逐一对比数组元素,多余的尾部元素报告为 added/deleted。 |
'lcs' | 使用最长公共子序列算法,为有序数组检测最小差异。 |
'unordered' | 将数组视为多重集合,无论位置匹配相等元素。 |
JSONValueDiffType
type JSONValueDiffType = 'added' | 'deleted' | 'typeChanged' | 'valueChanged';
| 值 | 说明 |
|---|---|
'added' | 值存在于 contrastJSON 但不存在于 baseJSON。 |
'deleted' | 值存在于 baseJSON 但不存在于 contrastJSON。 |
'typeChanged' | 基准与对比值之间类型发生变化(如 number → string)。 |
'valueChanged' | 类型不变但值发生变化。 |
JSONValueDifference
| 字段 | 类型 | 说明 |
|---|---|---|
pathSegments | string[] | 差异值的路径片段。对象键原样出现;数组索引以 '[n]' 形式出现(如 ['users', '[0]', 'name'])。 |
pathString | string | 同一路径的点表示法字符串,数组索引保留为方括号后缀(如 'users[0].name')。 |
pathBelongsTo | 'base' | 'contrast' | 'both' | 路径所属一侧。deleted 为 'base',added 为 'contrast',valueChanged 和 typeChanged 为 'both'。 |
diffType | JSONValueDiffType | 该路径检测到的差异类型。 |
许可证
MIT