0

I have an array that contains three book objects. Each book object has an array of bookIds . I want to filter by bookId (3,1) in a fast and efficient way since my array will grow up easly in the future. I tried with map, but it change my original array even with a deepCopy ! Is there a way to use the filter function instead without using recursivity ?

this.booksList = 
    [
      {
        "books": [
          {
            "bookId": 3
          },
          {
            "bookId": 2
          }
        ],
        "id": 1,
        "name": "Name 1",
        "description": "desc 1"
      },
      {
        "books": [
          {
            "bookId": 5
          },
          {
            "bookId": 2
          }
         ],
         "id": 2,
         "name": "Name 2",
         "description": "desc 2"
      },
      {
        "books": [
          {
            "bookId": 1
          },
          {
            "bookId": 3
          }
         ],
         "id": 3,
         "name": "Name 3",
         "description": "desc 3"
      }
    ]

The map approach :

let results = this.books.map(function (book) {
            book.books = book.books.filter(x => x.bookId == 1 || x.bookId == 3);
            return book;
        }).filter(({ books }) => books.length);

Result with map : not expected result !

[
  {
    "books": [
      {
        "bookId": 3
      }
    ],
    "id": 1,
    "name": "Name 1",
    "description": "desc 1"
  },
  {
    "books": [
      {
        "bookId": 1
      },
      {
        "bookId": 3
      }
     ],
     "id": 3,
     "name": "Name 3",
     "description": "desc 3"
  }
]

expected results :

[
  {
    "books": [
      {
        "bookId": 3
      },
      {
        "bookId": 2
      }
    ],
    "id": 1,
    "name": "Name 1",
    "description": "desc 1"
  },
  {
    "books": [
      {
        "bookId": 1
      },
      {
        "bookId": 3
      }
     ],
     "id": 3,
     "name": "Name 3",
     "description": "desc 3"
  }
]

Thanks,

5
  • map didn't change your original array. Commented Sep 19, 2020 at 23:26
  • yes it does ! otherwise i will keep the map solution. See my post that i just updated Commented Sep 19, 2020 at 23:28
  • You passed a function that changes books as the callback to map. map just calls you callback and returns its result. Commented Sep 19, 2020 at 23:29
  • Try const results = books.map(x => ({...x, books: x.books.filter(b => b.bookId === 1 || b.bookId === 3)})) Commented Sep 19, 2020 at 23:32
  • i have the same results as the not expected result in my post but with your version my original array didn't change this time, so that's a good start :) Commented Sep 19, 2020 at 23:45

2 Answers 2

2

I think you are looking for filter and some -

const input =
  [{books:[{bookId:3},{bookId:2}],id:1,name:"Name 1",description:"desc 1"},{books:[{bookId:5},{bookId:2}],id:2,name:"Name 2",description:"desc 2"},{books:[{bookId:1},{bookId:3}],id:3,name:"Name 3",description:"desc 3"}]

const query =
  [3, 1]

const result =
  input.filter(({ books = [] }) =>
    books.some(({ bookId = null }) => query.includes(bookId))
  )

console.log(JSON.stringify(result, null, 2))

Output -

[
  {
    "books": [
      {
        "bookId": 3
      },
      {
        "bookId": 2
      }
    ],
    "id": 1,
    "name": "Name 1",
    "description": "desc 1"
  },
  {
    "books": [
      {
        "bookId": 1
      },
      {
        "bookId": 3
      }
    ],
    "id": 3,
    "name": "Name 3",
    "description": "desc 3"
  }
]
Sign up to request clarification or add additional context in comments.

Comments

0

const booksList=[
  {books:[{bookId:3},{bookId:2}],id:1,name:"Name 1",description:"desc 1"},
  {books:[{bookId:5},{bookId:2}],id:2,name:"Name 2",description:"desc 2"},
  {books:[{bookId:1},{bookId:3}],id:3,name:"Name 3",description:"desc 3"},
];

const byBookIDs = (...IDs) =>
  booksList.filter(b => b.books.some(b => IDs.includes(b.bookId)));

console.log(byBookIDs(1, 3));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.