-1

I want the user base to be able to filter by several parameters.

I have an object with parameters to filter:

const options = { _id: 'fu4gosy5hjruierbweyuu5u6hh', name: "Jhon" }

and an array of objects with a database of users:

const base = [
    { _id: '5h245jg2h4gjh2jh5g2j4hg52g', name: 'Jhon' },
    { _id: 'fdgd6fgd7f84b5hhjfdghj4hgg', name: 'Jhon' },
    { _id: 'fu4gosy5hjruierbweyuu5u6hh', name: 'Jhon' }
]

Of course you could make everything much simpler, namely to filter by unique id, but you have to understand that filtering has to be by several parameters and parameters can be completely different.

I tried using every() in filter().

Joshua Ooi
  • 1,139
  • 7
  • 18
  • 1
    "options" is not a valid array, did you mean to make it an object? – Anton Podolsky Feb 23 '23 at 18:23
  • What type of output do you want the filter to obtain? Does it only filter and return the item that having exactly the same id and name? Or returning items that either the id or name is same as the option? – Joshua Ooi Feb 23 '23 at 18:25
  • The database must be filtered by the parameters that are specified in the "options" object. And the result should output as a complete object from the database. – ФОЗАН Feb 23 '23 at 18:28
  • Doesn't look like a database to me. It just looks like an array. And your options doesn't look like an array, it also looks like an object. It shouldn't be too hard to write the 1 liner filter. Unless, of course, the question isn't really explaining the problem clearly enough. – Stephen Quan Feb 23 '23 at 18:30
  • Does this answer your question? [javascript filter array multiple conditions](https://stackoverflow.com/questions/31831651/javascript-filter-array-multiple-conditions) – Yogi Feb 23 '23 at 18:42
  • Down vote for lack of research. There are many similar previous questions which OP might have used to resolve the problem. – Yogi Feb 23 '23 at 18:45

2 Answers2

2

In your filter function you can loop through all the object properties:

const find = (data, query) => 
  data.filter(entry => {
    for(const [key, value] of Object.entries(query)) {
      if(entry[key] !== value) return false
    }
    return true
  })

const base = [{
    _id: '5h245jg2h4gjh2jh5g2j4hg52g',
    name: 'Jhon'
  },
  {
    _id: 'fdgd6fgd7f84b5hhjfdghj4hgg',
    name: 'Jhon'
  },
  {
    _id: 'fu4gosy5hjruierbweyuu5u6hh',
    name: 'Jhon'
  },
  {
    _id: 'fu4gosy5hjruierbweyuu5u6hh',
    name: 'Jhon',
    entry: 2 // the 'find' function only cares about the given options
  }
]

const options = {
  _id: 'fu4gosy5hjruierbweyuu5u6hh',
  name: "Jhon"
}
console.log(find(base, options))
console.log(find([
  { name: "apple", category: "fruit" },
  { name: "celery", category: "vegetable" },
  { name: "mushroom", category: "vegetable" },
  { name: "lemon", category: "fruit" },
  { name: "watermelon", category: "fruit" },
], { category: "fruit" }))
code
  • 5,690
  • 4
  • 17
  • 39
0

The filter function can be given greater versatility by being used in conjunction with a lambda. I'm not familiar with filter, but it seems filter places every iterated object into the function provided and breaks if you straightfowardly try to add more parameters to said function.

So this

function is_bigger_than(element, value) {
  return element > value
}

filter(is_bigger_than(10))

wouldn't work because the function provided executes before an object can even be placed into it for evaluation. That means a lambda, which won't run so soon, is needed.

It would look like this

filter((automatically_inserted_element) => is_bigger_than(element, value))

you can just then tweak with is_bigger_than to accept more parameters and whether it works on a "both" or "or" basis.

function is_bigger_than(element, value, start_value) {
  return (element > value && element.toString().slice(0, 1) == start_value)
}
code
  • 5,690
  • 4
  • 17
  • 39
FooBar
  • 1
  • 1
  • I'm not exactly sure how this answers the question? Functions as well as lambdas (they're called arrow functions in JS) are both valid to enter into a callback (when you pass a function as an argument), you just don't call it. You can use currying to achieve this: `function is_bigger_than(x) { return element => element > x; }` then you can do `array.filter(is_bigger_than(10))`. I'm still not sure how this answers the OP's question at all though. – code Feb 23 '23 at 18:52
  • I see thanks. I figured OP got stuck on deciding how to check the inputs against whatever parameters the users provide and just provided a way to do that. The final iteration of is_bigger_than takes multiple parameters in for filter, which is essentially what OP is asking for. Contextualizing it for their use case is likely a straightfoward task for them. – FooBar Feb 23 '23 at 19:01
  • But the parameters appear to be dynamic and take an input object. – code Feb 23 '23 at 19:02
  • Yea, I should have also placed the filter function itself into another function that accepts and passes those inputs into the callback. – FooBar Feb 23 '23 at 19:05