You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改JS数组对象去重方法以支持嵌套键(如bounds)去重?

基于嵌套对象的数组去重问题

我找到一段可基于顶层多键对数组对象去重的代码:

const browsers = [ 
    { os: "OS X", 
        os_version: "Catalina", 
        browser: "chrome", 
        browser_version: "30.0" 
    }, 
    { 
        os: "Windows", 
        os_version: "7", 
        browser: "chrome", 
        browser_version: "40.0" 
    }, 
    { 
        os: "Windows", 
        os_version: "7", 
        browser: "chrome", 
        browser_version: "50.0" 
    } 
]; 


const makeUnique = (array = [], keys = []) => { 
    if (!keys.length || !array.length) return []; 
    
    return array.reduce((list, item) => { 
        const hasItem = list.find(listItem => keys.every(key => listItem[key] === item[key]) ); 
        if (!hasItem) list.push(item); 
        return list; 
    },[]); 
}; 


console.log(makeUnique(browsers, ["os", "os_version"]));

但我的数组包含嵌套的bounds对象,示例如下:

const tiles = [
    {
        name: "pattern1",
        type: "jpg",
        size: 1024,
        bounds:{topleft_x: 45, topleft_y: 45, downright_x: -45, downright_y: -45},
    },
    {
        name: "pattern2",
        type: "jpg",
        size: 1024,
        bounds:{topleft_x: 90, topleft_y: 90, downright_x: 45, downright_y: 45},
    },
    {
        name: "pattern3",
        type: "jpg",
        size: 1024,
        bounds:{topleft_x: 45, topleft_y: 45, downright_x: -45, downright_y: -45},
    },
    //...
];

需要修改makeUnique方法,使其能基于嵌套的bounds子键进行去重,去除重复的bounds项。


解决方案

方案1:基于完整嵌套对象去重

如果需要整个bounds对象完全一致才判定为重复,可以添加深度比较对象的逻辑:

// 辅助函数:深度比较两个对象是否相等
const isEqual = (obj1, obj2) => {
    if (obj1 === obj2) return true;
    if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
        return false;
    }
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);
    if (keys1.length !== keys2.length) return false;
    for (const key of keys1) {
        if (!keys2.includes(key) || !isEqual(obj1[key], obj2[key])) {
            return false;
        }
    }
    return true;
};

const makeUnique = (array = [], keys = []) => {
    if (!keys.length || !array.length) return [];
    
    return array.reduce((list, item) => {
        const hasItem = list.find(listItem => 
            keys.every(key => {
                const val1 = item[key];
                const val2 = listItem[key];
                // 若是对象则深度比较,否则直接值比较
                return typeof val1 === 'object' && val1 !== null ? isEqual(val1, val2) : val1 === val2;
            })
        );
        if (!hasItem) list.push(item);
        return list;
    }, []);
};

// 使用方式:传入["bounds"]作为去重键
console.log(makeUnique(tiles, ["bounds"]));

方案2:基于嵌套键路径去重

如果需要灵活指定bounds内的具体子键(比如仅基于topleft_x和topleft_y去重),可以支持解析键路径:

// 辅助函数:根据键路径(如"bounds.topleft_x")获取对象值
const getValueByPath = (obj, path) => {
    return path.split('.').reduce((curr, key) => curr?.[key], obj);
};

const makeUnique = (array = [], keys = []) => {
    if (!keys.length || !array.length) return [];
    
    return array.reduce((list, item) => {
        const hasItem = list.find(listItem => 
            keys.every(key => getValueByPath(item, key) === getValueByPath(listItem, key))
        );
        if (!hasItem) list.push(item);
        return list;
    }, []);
};

// 使用方式:传入bounds的子键路径数组
console.log(makeUnique(tiles, [
    "bounds.topleft_x", 
    "bounds.topleft_y", 
    "bounds.downright_x", 
    "bounds.downright_y"
]));

适用场景

  • 方案1:适用于需要确保整个bounds对象的所有键值都完全相同才去重的场景。
  • 方案2:适用于只需匹配bounds内指定子键即可去重的场景,灵活性更高。

内容的提问来源于Stack Exchange,提问作者Spiri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 04:20:31