0

I have an array like such

const arr = [
  {
    id: '123',
    book: {isNew: true}
  },
  {
    id: '123',
    book: {isNew: false}
  },
  {
    id: '123',
    book: {isNew: false}
  },
  {
    id: '123',
    book: {isNew: true}
  },
]

I am tring to filter the array to return only the objects where the book object has isNew as true.

I was attempting to something like this

arr.filter(obj => {
  // Use a forEach to determine which book obj is new
}

However a forEach can't return any values.

EDIT

Seems like my original way of explaining was a bit lacking.

Within each obj of the array, there can be multiple "Book" objects. All with dynamic keys. I want the object with at least one "Book" object that is new.

For example:

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},
  },
]

So my filtered array will consist of the first and last element of the original array

Lemnns
  • 35
  • 1
  • 6
  • 3
    You don't need to use `forEach`. You have the object in `obj`. Test `obj.book.isNew`. – jarmod Aug 03 '20 at 20:58
  • these Array methods do the forEaching for you. just supply the specific, individual object, filter. – radarbob Aug 03 '20 at 20:59
  • I forgot the mention the book obj was just an example. In my project the key for the object is dynamic – Lemnns Aug 03 '20 at 21:02

1 Answers1

1

How about something like that

arr.filter(({ book: { isNew } }) => isNew)

I'm just using a data structure to get the isNew property and return the TRUE value only

UPDATE :

the ({ book: { isNew } }) it's just another way to write

arr.filter((object) => object.book.isNew)

UPDATE :

The question was about dynamic [key] I came with 2 solution 1 -

arr.filter((item) => {
  for (const key of Object.keys(item)) {
    const { isNew } = item[key]
    if (typeof isNew === 'boolean') return isNew
  }
})

Where I'm filtering and looping for each key and checking if there is a property with key [ isNew ]
if there is any will return it

Another way to write it

arr.filter((item) => {
  for (const key of Object.keys(item))
    if (item[key].hasOwnProperty('isNew')) return item[key].isNew
})
  • Yes that would work, but I did a bad job asking my question. The book object was just an example. In my project, that object is dynamic, so I can't just target book. And there might be multiple "books" per obj. So something like { id: 123, key1: {isNew: true} key2: {isNew: false} } – Lemnns Aug 03 '20 at 21:07
  • @Lemnns Oh it's okay, You can do something like Which I don't really like it ```js arr.filter((item) => { for (const key of Object.keys(item)) if (item[key].hasOwnProperty('isNew')) return item[key].isNew }) ``` of you can do something like ```js arr.filter((item) => { for (const key of Object.keys(item)) { const { isNew } = item[key] if (typeof isNew === 'boolean') return isNew } }) ``` – Mustafa Ali Aug 03 '20 at 22:01
  • @Lemnns I'll be updating my answer soon <3 – Mustafa Ali Aug 03 '20 at 22:01