方法 1: 使用Map根据特定键去重JSON对象数组(支持自定义条件)
function uniqueJsonByKey(arr, key, customCondition = null) {
const map = new Map();
return arr.filter(item => {
const keyValue = item[key];
if (customCondition) {
const conditionKey = customCondition(item);
if (!map.has(conditionKey)) {
map.set(conditionKey, true);
return true;
}
return false;
}
if (!map.has(keyValue)) {
map.set(keyValue, true);
return true;
}
return false;
});
}
// 测试JSON数组
const testJsonArr1 = [
{id: 1, name: 'John', age: 25, department: 'IT'},
{id: 2, name: 'Jane', age: 30, department: 'HR'},
{id: 1, name: 'John', age: 25, department: 'IT'},
{id: 3, name: 'Bob', age: 35, department: 'IT'},
{id: 2, name: 'Jane', age: 30, department: 'HR'}
];
// 调用 - 基本键去重
const resultJson1 = uniqueJsonByKey(testJsonArr1, 'id');
// 输出
console.log('1. 根据id键去重结果:', resultJson1);
// 调用 - 自定义条件去重(根据部门和年龄)
const resultJson1Custom = uniqueJsonByKey(testJsonArr1, 'id', item => `${item.department}-${item.age}`);
// 输出
console.log('1. 自定义条件去重结果:', resultJson1Custom);
方法 2: 使用JSON字符串化完全去重(支持自定义条件)
function uniqueJsonComplete(arr, customCondition = null) {
const seen = new Set();
return arr.filter(item => {
const key = customCondition ? customCondition(item) : JSON.stringify(item);
if (seen.has(key)) {
return false;
}
seen.add(key);
return true;
});
}
// 测试JSON数组
const testJsonArr2 = [
{id: 1, name: 'Alice', skills: ['js', 'css'], level: 'senior'},
{id: 2, name: 'Bob', skills: ['python'], level: 'junior'},
{id: 1, name: 'Alice', skills: ['js', 'css'], level: 'senior'},
{id: 3, name: 'Charlie', skills: ['java'], level: 'mid'},
{id: 2, name: 'Bob', skills: ['python'], level: 'senior'}
];
// 调用 - 完全去重
const resultJson2 = uniqueJsonComplete(testJsonArr2);
// 输出
console.log('2. 完全去重结果:', resultJson2);
// 调用 - 自定义条件去重(根据技能数组)
const resultJson2Custom = uniqueJsonComplete(testJsonArr2, item => JSON.stringify(item.skills.sort()));
// 输出
console.log('2. 自定义技能去重结果:', resultJson2Custom); 方法3: 使用reduce根据多个键去重(支持自定义条件)
function uniqueJsonByMultipleKeys(arr, keys, customCondition = null) {
const seen = new Set();
return arr.filter(item => {
const keyStr = customCondition ? customCondition(item) : keys.map(key => item[key]).join('|');
if (seen.has(keyStr)) {
return false;
}
seen.add(keyStr);
return true;
});
}
// 测试JSON数组
const testJsonArr3 = [
{id: 1, name: 'John', department: 'IT', age: 25, salary: 5000},
{id: 2, name: 'Jane', department: 'HR', age: 30, salary: 6000},
{id: 1, name: 'John', department: 'IT', age: 25, salary: 5500},
{id: 3, name: 'Bob', department: 'IT', age: 35, salary: 7000},
{id: 2, name: 'Jane', department: 'HR', age: 30, salary: 6000}
];
// 调用 - 多键去重
const resultJson3 = uniqueJsonByMultipleKeys(testJsonArr3, ['id', 'name']);
// 输出
console.log('3. 多键去重结果:', resultJson3);
// 调用 - 自定义条件去重(根据部门和薪资范围)
const resultJson3Custom = uniqueJsonByMultipleKeys(testJsonArr3, ['id', 'name'], item =>
`${item.department}-${Math.floor(item.salary / 1000) * 1000}`
);
// 输出
console.log('3. 自定义薪资范围去重结果:', resultJson3Custom); 方法4: 使用对象哈希去重(支持自定义条件)
function uniqueJsonByHash(arr, customCondition = null) {
const seen = {};
return arr.filter(item => {
const hash = customCondition ? customCondition(item) : Object.keys(item)
.sort()
.map(key => `${key}:${item[key]}`)
.join('#');
if (seen[hash]) {
return false;
}
seen[hash] = true;
return true;
});
}
// 测试JSON数组
const testJsonArr4 = [
{name: 'Alice', age: 25, city: 'New York', score: 85},
{name: 'Bob', age: 30, city: 'London', score: 92},
{name: 'Alice', age: 25, city: 'New York', score: 85},
{name: 'Charlie', age: 35, city: 'Paris', score: 78},
{age: 30, city: 'London', name: 'Bob', score: 92}
];
// 调用 - 哈希去重
const resultJson4 = uniqueJsonByHash(testJsonArr4);
// 输出
console.log('4. 哈希去重结果:', resultJson4);
// 调用 - 自定义条件去重(根据城市和分数段)
const resultJson4Custom = uniqueJsonByHash(testJsonArr4, item =>
`${item.city}-${Math.floor(item.score / 10) * 10}`
);
// 输出
console.log('4. 自定义分数段去重结果:', resultJson4Custom);
方法5: 使用Map和自定义比较函数去重(支持自定义条件)
function uniqueJsonCustom(arr, compareFn, customCondition = null) {
const result = [];
arr.forEach(item => {
const shouldAdd = customCondition ?
!result.some(existingItem => customCondition(existingItem) === customCondition(item)) :
!result.some(existingItem => compareFn(existingItem, item));
if (shouldAdd) {
result.push(item);
}
});
return result;
}
// 测试JSON数组
const testJsonArr5 = [
{id: 1, name: 'John', timestamp: '2023-01-01', status: 'active'},
{id: 2, name: 'Jane', timestamp: '2023-01-02', status: 'inactive'},
{id: 1, name: 'John', timestamp: '2023-01-03', status: 'active'},
{id: 3, name: 'Bob', timestamp: '2023-01-04', status: 'active'},
{id: 2, name: 'Jane', timestamp: '2023-01-05', status: 'active'}
];
// 自定义比较函数
const compareById = (a, b) => a.id === b.id;
// 调用 - 自定义比较去重
const resultJson5 = uniqueJsonCustom(testJsonArr5, compareById);
// 输出
console.log('5. 自定义比较去重结果:', resultJson5);
// 调用 - 自定义条件去重(根据状态和时间范围)
const resultJson5Custom = uniqueJsonCustom(testJsonArr5, compareById, item =>
`${item.status}-${item.timestamp.slice(0, 7)}` // 按年月分组
);
// 输出
console.log('5. 自定义状态和时间去重结果:', resultJson5Custom);