1

I'm trying to make a search function. The number of filters will change dynamically, a number of keys can be different, and the number of values, too.

My code looks like:

var data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Resla"}]
var keys = ["color", 'model'];
var values = ["Re"];

var result = data.filter(function(e) {
  return keys.every(function(a) {
    return values.includes(e[a])
  })
})
console.log(result);

Is it possible to search with - startsWith() and not includes()? I guess everything should be in toLowerCase() as well?

Also can I have two separate results as two arrays if results found in one key then it should individual array? So results will be like:

[{ colors: [{"id":"123","color":"Red","model":"Tesla"},{"id":"125","color":"Red","model":"Audi"}], models: [{"id":"126","color":"Blue","model":"Resla" }] }]

Thank you very much in advance.

2
  • You probably need keys.some and not every. Also, you need a nested values.some() or a regex separated by | to test Commented Jun 16, 2021 at 15:00
  • thank you @adiga I am really stack on making it working, can you please create an example code for me? Commented Jun 16, 2021 at 15:02

2 Answers 2

2
  • You need to check keys.some and not keys.every. This will check if the value is part of at least one of the keys and not all of them.

  • For values, you could create a dynamic regex with alternation and test value against the regex. So, values = ["Re", "Ho"] will create /Re|Ho/

const data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Resla"}],
      keys = ["color", 'model'],
      values = ["Ho"],
      regex = new RegExp(values.join('|')),
      output =  data.filter(e =>  keys.some(k => regex.test(e[k])) )
      
console.log(output);
If you want to individual results for each key, you can loop through the keys and check for the regex individually.

const data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Resla"}],
      keys = ["color", 'model'],
      values = ["Ho", "Re"],
      regex = new RegExp(values.join('|')),
      group = {}
      
for (const o of data) {
  for (const k of keys) {
    if (regex.test(o[k])) {
      group[k] ||= []
      group[k].push(o)
    }
  }
}

console.log(group);

Sign up to request clarification or add additional context in comments.

Comments

2

You can iterate through each key and value and look it up in object array using array#reduce

const data = [{"id":"123","color":"Red","model":"Tesla"},{"id":"124","color":"Black","model":"Honda"},{"id":"125","color":"Red","model":"Audi"},{"id":"126","color":"Blue","model":"Resla"}],
      keys = ["color", 'model'],
      values = ["Re"],
      initial = Object.assign(...keys.map(k => ({[`${k}s`]: [] }))),
      result = data.reduce((r, o) => {
       keys.forEach(k => {
        values.forEach(val => {
          if(o[k] && o[k].startsWith(val)) {
            r[`${k}s`].push(o);
          }
        });
       });
       return r;
      },initial);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1 Comment

Hi @hassanimam I really appreciate your example which works very well! Thanks a million!

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.