javascript 根据多个子项使数组中的对象唯一

mklgxw1f  于 2023-01-07  发布在  Java
关注(0)|答案(2)|浏览(99)

我在
https://blog.adriaan.io/make-array-with-objects-unique-on-multiple-keys-in-javascript.html

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"]));

我想在我的objectarray中使用这个方法,但是我在一个键中使用键。有人知道如何使这个方法适应我的例子以便忽略双边界吗?

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},
    },
    //...
];
qcbq4gxm

qcbq4gxm1#

你需要一个遍历函数这个函数得到一个对象和一个叫做path的字符串,path类似于bounds.topleft_y

function traverse(obj, path) {
    if (!path.includes('.')) return obj[path];
    return path.split('.').reduce((a, k) => a[k], obj)
}

并且需要更改makeUnique函数

const makeUnique = (array = [], keys = []) => {
    if (!keys.length || !array.length) return []; 

    return array.reduce((list, item) => {
        const hasItem = list.find(listItem => keys.every(key => traverse(listItem, key) === traverse(item, key)));
        console.log(data, item, hasItem)
        if (!hasItem) list.push(item);
        return list;
    }, [])
}

下面是如何使用它

makeUnique(data, ['type', 'bounds.topleft_y'])
pdkcd3nj

pdkcd3nj2#

任何重复数据删除算法的关键在于如何确定相等性。在您提供的示例算法中,检查listItem[key] === item[key]时会出现相等性。严格相等(===)非常适合比较基元值,但没有内置的方法来比较对象(如bounds)。因此,您必须使用自定义值相等函数。
有一个很棒的npm包value-equal可以帮你做到这一点,你也可以查看它的实现here
一旦你有了一个valueEqual()函数,你可以把它转换成如下的算法:

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

然后,您可以像以前一样调用算法:

console.log(makeUnique(tiles, ["type", "bounds"]));

相关问题