简体   繁体   中英

Javascript - filtering a list: how can I find an intersection between an array with objects including array and an array?

How can I filter a list (array with objects) with a filter list (array) and find intersections? I add to the filter array every time a user checks the checkbox clicking on particular filter. When user unchecks the checkbox I remove from filter array. Somehow whateever i try doing, i always return the entire reviews array including ALL not filtered items. Why? Thanks!!

const reviews = [
{
  title: "item 1",
  filter_results: {
    features: ["message", "call"],
    pricing: ["Business", "Free", "Whatever"],
    rating: [1]
  }
},
  {
  title: "item 2",
  filter_results: {
    features: ["call", "copy", "paste"],
    pricing: ["Business"],
    rating: [1]
  }
},
  {
  title: "item 3",
  filter_results: {
    features: ["copy", "connect", "wifi"],
    pricing: ["Free",
    rating: [2]
  }
 }
]

const filteredReviews = {
 pricing_options: ["Business"],
 popular_features: ["copy, call"],
 rating: [1, 2]
}

const update = (reviews, categoryName) => {
  if (categoryName) {
    return reviews.filter(review => {
      return review.filter_results[categoryName].filter(value => {
        if (filteredReviews[categoryName].includes(value)) {
          return review
        } 
      })
    })
  } else {
    return reviews
  }
}
  update(reviews, "pricing")

Return a boolean on filter callback, and do a better filtering mechanism:

const update = (reviews, filters) => {
  if (filters) {
    return reviews.filter(review => 
        Object.entries(filters)
          // Change to `some` if the filters are OR'ed instead of AND'ed
          .every(
            ([filter_key, filter_values]) =>
              // Change `some` to `every` if all elements in the
              // userFilter[*] array MUST be matched instead of some of them
              filter_values.some( (filter_value) =>
                review.filter_results[filter_key]
                  .includes(filter_value)
              )
          )
    )
  } else {
    return reviews
  }
}

// Fix variables names:
// - `userFilters` contains the filters selected by the user
// - `filteredReviews` contains the array of reviews, resulting from
//   filtering the reviews using the `userFilters`

// Fix key names: Use same keys than in reviews, instead of:
// - `pricing_options` => `pricing`
// - `popular_features` => `features`
const userFilters = {
  pricing: ["Business"],
  // Transformed/fixed to 2 values. Was it a typo?
  features: ["copy", "call"],
};

const filteredReviews = update(reviews, userFilters);

Filter callback function should return a "boolean", you are returning arrays which evaluate always to "true".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM