【问题标题】:JavaScript: How to filter array by values nested in object 2 level deepJavaScript:如何按嵌套在对象 2 级深处的值过滤数组
【发布时间】:2020-08-03 22:41:10
【问题描述】:

我有一个对象数组。

在数组的每个对象中,可以有多个“Book”对象,它们都具有动态键。我想要至少有一个新的“书”对象的对象。

例如:

const arr = [
  {
    id: '123',
    book1242: {isNew: true},
    book9023: {isNew: false},
  },
  {
    id: '123',
    book0374: {isNew: false},
    book9423: {isNew: false},
  },
  {
    id: '123',
    book8423: {isNew: false},
    book9023: {isNew: false},
  },
  {
    id: '123',
    book6534: {isNew: true},
    book9313: {isNew: false},
  },
]

所以我的过滤数组将由原始数组的第一个和最后一个元素组成

预期的过滤数组

const arr = [
  {
    id: '123',
    book1242: {isNew: true},
    book9023: {isNew: false},
  },
  {
    id: '123',
    book6534: {isNew: true},
    book9313: {isNew: false},
  },
]

我曾尝试使用filtermap,但我必须循环并检查哪本书是新的,但我不确定如何在过滤器中返回该对象。

【问题讨论】:

    标签: javascript arrays object


    【解决方案1】:

    听起来你想要这样的东西:

    arr.filter((o) => Object.values(o).some((b) => b.isNew))

    您的数组是否只有idbookwxyz 的键?如果不是,您可能需要检查这些值以确保它们不是未定义的

    您还可以使用 Object.entries 和正则表达式显式检查密钥:

    arr.filter((o) => Object.entries(o).some(([key, value]) => /book\d{4}/.test(key) && value.isNew))

    【讨论】:

    • @RokoC.Buljan 好点,我试图找到一种方法来处理数组中可能包含其他可能包含 isNew 的事实,但这不太可能我已经改变了答案.
    • 非常简单。干得好!
    • PS,为了提供更长的寿命,而不是或依赖4 - 我会做/book\d+$/ 这样在 N 年后我不需要关心关于仅仅因为图书馆有更多书籍而出现的错误。
    【解决方案2】:

    您可以将Array#someObject.values 一起使用。

    const arr = [ { id: '123', book1242: {isNew: true}, book9023: {isNew: false}, }, { id: '123', book0374: {isNew: false}, book9423: {isNew: false}, }, { id: '123', book8423: {isNew: false}, book9023: {isNew: false}, }, { id: '123', book6534: {isNew: true}, book9313: {isNew: false}, }, ];
    const res = arr.filter(obj=>Object.values(obj).some(({isNew})=>isNew));
    console.log(res);

    【讨论】:

    • 只要有任何非对象值,例如原始布尔值或浮点数,它就不起作用。
    • @w35l3y 你试过了吗?它工作正常。实际上,示例中的 id 是一个原语。
    • 你是对的。它不适用于 nullundefined 仅。
    【解决方案3】:

    const arr=[{id:"123",book1242:{isNew:!0},book9023:{isNew:!1}},{id:"123",book0374:{isNew:!1},book9423:{isNew:!1}},{id:"123",book8423:{isNew:!1},book9023:{isNew:!1}},{id:"123",book6534:{isNew:!0},book9313:{isNew:!1}}];
    
    const res = arr.filter(obj => {
      for(const [key, val] of Object.entries(obj)){
        if(key.substring(0,4) === 'book' && val.isNew === true){
          return obj
        }
       }
    })
    
    console.log(res)

    【讨论】:

    • 这当然是最明确和最安全的一个,实际上检查密钥前面有book。你可以用some替换for循环,过滤器只需要你返回一个布尔值,所以你可以直接返回key.substring(0,4) === 'book' && val.isNew
    【解决方案4】:
     let sorted =[]
      arr.forEach((el, i) => {
             let obj_values = Object.values(el);
             obj_values = obj_values.filter((elem) => typeof elem == 'object' && elem.isNew == true);
    if(obj_values.length) sorted.push(arr[i])
         })
    

    【讨论】:

      猜你喜欢
      • 2019-08-10
      • 1970-01-01
      • 2022-01-12
      • 2017-06-29
      • 2019-01-29
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 2022-01-09
      相关资源
      最近更新 更多