简体   繁体   中英

Filter Object Array values based on user input

I want to filter the object array values based on user input.

This is the jsfiddle :

 // Copied from https://github.com/tc39/proposal-object-values-entries/blob/master/polyfill.js const reduce = Function.bind.call(Function.call, Array.prototype.reduce); const isEnumerable = Function.bind.call(Function.call, Object.prototype.propertyIsEnumerable); const concat = Function.bind.call(Function.call, Array.prototype.concat); const keys = Reflect.ownKeys; if (!Object.values) { Object.values = function values(O) { return reduce(keys(O), (v, k) => concat(v, typeof k === 'string' && isEnumerable(O, k) ? [O[k]] : []), []); }; } // Copied code ends here; let data = { Belgien: [{ code: "BRU", name: "Bryssel", aliases: "Bryssel,BRU,Belgien" }], Cypern: [{ code: "LCA", name: "Larnaca", aliases: "Larnaca,LCA,Cypern,Ayia Napa,Protaras,Fig Tree Bay,Larnaca" }, { code: "PFO", name: "Paphos", aliases: "Paphos,PFO,Cypern" } ] } let userInput = "lar"; let filteredData = Object.values(data).map(values => values.filter(value => value.name.toLowerCase().indexOf(userInput) !== -1)); console.log(filteredData); 

The issue is that I get the values properly filtered, but I do not get the keys associated with these values, in this example the countries.

Thanks in advance.

You can use the function reduce and filter the data using the functions filter and indexOf .

This alternative uses the function Object.keys to be able to recover the desired key.

 let data = { Belgien: [{ code: "BRU", name: "Bryssel", aliases: "Bryssel,BRU,Belgien" }], Cypern: [{ code: "LCA", name: "Larnaca", aliases: "Larnaca,LCA,Cypern,Ayia Napa,Protaras,Fig Tree Bay,Larnaca" }, { code: "PFO", name: "Paphos", aliases: "Paphos,PFO,Cypern" } ]}, userInput = "lar", filteredData = Object.keys(data).reduce((a, k) => { a[k] = data[k].filter(({name}) => name.toLowerCase().indexOf(userInput) > -1); return a; }, {}); console.log(filteredData); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

You could iterate over the keys and return an object with only filtered data.

 var data = { Belgien: [{ code: "BRU", name: "Bryssel", aliases: "Bryssel,BRU,Belgien" }], Cypern: [{ code: "LCA", name: "Larnaca", aliases: "Larnaca,LCA,Cypern,Ayia Napa,Protaras,Fig Tree Bay,Larnaca" }, { code: "PFO", name: "Paphos", aliases: "Paphos,PFO,Cypern" }] }, userInput = "lar", filteredData = Object.keys(data).reduce((r, k) => { var temp = data[k].filter(({ name }) => name.toLowerCase().includes(userInput)); if (temp.length) { r[k] = temp; } return r; }, {}); console.log(filteredData); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

You could get the job done using Object.entries like this:

let filteredData = Object.entries(data).reduce((acc, values) => {
  const value = values[1].filter(value =>
      value.name.toLowerCase().indexOf(userInput) !== -1),
    key = values[0];
  acc[key] = value;
  return acc;
}, {});

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