如何使用UnderscoreJS过滤对象数组?(已解决)
对象数组筛选完全匹配元素的解决方案
嗨,我明白你为啥遇到这个问题啦!对象数组里直接用普通的全等比较肯定拿不到结果,因为对象是引用类型——哪怕两个对象的键值对完全一样,它们在内存里的地址是不同的,直接===比较只会返回false,自然筛选出空数组啦。
下面给你两种靠谱的解决办法,不管用不用UnderscoreJS都能搞定:
方法一:用UnderscoreJS的_.isEqual()做深度比较
Underscore自带的_.isEqual()方法专门用来做对象的深度相等判断,它会递归对比对象的每一个属性值,而不是只看引用地址。配合_.filter()就能轻松筛选出完全匹配的元素:
// 你的对象数组示例 const productList = [ { id: 3, name: 'Wireless Headphones', price: 99 }, { id: 1, name: 'Bluetooth Speaker', price: 49 }, { id: 3, name: 'Wireless Headphones', price: 99 } ]; // 你要匹配的目标对象 const targetProduct = { id: 3, name: 'Wireless Headphones', price: 99 }; // 正确的筛选写法 const matchedItems = _.filter(productList, item => _.isEqual(item, targetProduct)); // 此时matchedItems会包含两个符合条件的对象
之前你得到空数组,大概率是直接写了item === targetProduct这种引用比较,换成_.isEqual()就没问题啦。
方法二:原生JavaScript实现(不用Underscore)
如果你不想依赖库,有两种思路:
用
JSON.stringify()快速比较(适合纯数据对象,属性顺序一致的情况):const matchedItems = productList.filter(item => JSON.stringify(item) === JSON.stringify(targetProduct) );注意:这个方法有局限性——如果两个对象的属性顺序不同(比如
{a:1, b:2}和{b:2, a:1}),JSON.stringify后的字符串会不一样,导致判断错误。自己实现深度比较函数(更严谨):
写一个递归函数来对比对象的每一个属性,比如:function deepEqual(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) || !deepEqual(obj1[key], obj2[key])) { return false; } } return true; } // 然后用这个函数筛选 const matchedItems = productList.filter(item => deepEqual(item, targetProduct));
补充说明
UnderscoreJS文档里的filter示例大概率是针对字符串、数字这类基本类型数组的,所以直接用全等比较就行,但对象数组必须用深度比较才能匹配到内容完全一致的元素哦。
内容的提问来源于stack exchange,提问作者Arnell Vasquez C
相关产品推荐
相关产品推荐

