【问题标题】:Filter object base on parameters - Check if Object values are equal to parameters ES6根据参数过滤对象 - 检查对象值是否等于参数 ES6
【发布时间】:2021-03-16 13:28:42
【问题描述】:

我在使用对象过滤器时遇到问题。

我想要做的是在给定参数等于对象值时过滤对象数组。 并且仅当对象中的所有值都等于这些参数时才返回对象。

let payload = {
   product: 'product1', 
   author = {
      id: 12,
      name = 'author1'
    }
}

Array I want to filter based on above parameters:
let data = [
    {
        product: 'product1,
        author: { id: 12, name: 'author1'}
    },
    {
        product: 'product1,
        author: { id: 20, name: 'author2'}
    },
     {
        product: 'product3,
        author: { id: 12, name: 'author1'}
    },
]

在这个例子中作为一个参数:product1 另一个 id author {id: 12, name: 'author1'} 那么只有一个对象匹配:

let result = [{
        product: 'product1,
        author: { id: 12, name: 'author1'}
    }]

我的做法是:

let keys = Object.keys(paylaod)

let matched
keys.forEach(key => {
    matched = data.filter(item => item[key] == payload[key])
})

我得到的是:

matched= [
    {
        product: 'product1,
        author: { id: 12, name: 'author1'}
    },
    {
        product: 'product1,
        author: { id: 20, name: 'author2'}
    },
]

我需要修改我的过滤函数才能得到结果:

matched = [{
        product: 'product1,
        author: { id: 12, name: 'author1'}
    }]

如果有所有给定的参数,有什么方法可以过滤对象??

【问题讨论】:

    标签: arrays json object ecmascript-6 filter


    【解决方案1】:

    由于您的“作者”键指向一个对象,因此您将无法使用 == 运算符来建立相等性。在 JS 中使用 == 比较对象只会在它们是完全相同的对象时返回 true,而不是如果它们具有相同的内容。 (想想同卵双胞胎。他们看起来完全一样,但他们不是同一个人)

    您将要检查深度平等。 Here's a good link that explains it better than I can

    选项#1:实现您自己的深度等于过滤器函数,该函数也将递归检查任何子对象是否相等。

    function deepEqual(object1, object2) {
      const keys1 = Object.keys(object1);
      const keys2 = Object.keys(object2);
    
      if (keys1.length !== keys2.length) {
        return false;
      }
    
      for (const key of keys1) {
        const val1 = object1[key];
        const val2 = object2[key];
        const areObjects = isObject(val1) && isObject(val2);
        if (
          areObjects && !deepEqual(val1, val2) ||
          !areObjects && val1 !== val2
        ) {
          return false;
        }
      }
    
      return true;
    }
    

    选项 #2: JSON.stringify

    字符串比较很简单!我们可以为此使用 == 运算符! 如果调用 JSON.stringify(payload),它将返回对象的字符串化版本以供比较

    JSON.stringify(payload) === JSON.stringify(item)
    

    但是,这有一个问题! JS 对象键不保证按特定顺序排列。如果两个对象的键顺序不同,则 JSON.stringify 方法将错误地返回它们不相等。以下对象是相等的,但使用此方法会被视为不相等

      let payload1 = {
           product: 'product1', 
           author = {
              id: 12,
              name = 'author1'
            }
        }
    
      let payload2 = {
           author = {
              id: 12,
              name = 'author1'
            }
           product: 'product1', 
        }
    
    
    JSON.stringify(payload1) === JSON.stringify(payload2) //RETURNS FALSE
    

    如果你能保证键的顺序,这是一种有效的比较方式!

    选项#3: 安装像Lodash 这样的第三方库,它将为您处理深度比较。函数 Lodash.isEqual(payload,item) 应该可以解决问题!

    【讨论】:

    • 您好,感谢您的回答。我做了深入检查平等,它工作得很好!
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2019-04-18
    相关资源
    最近更新 更多