Tengo un dict de un dict que se parece a esto:
{ "Chain1": { Country1: [ {name: "a", id: "1"}, {name: "b", id: "2"} ] }, "Chain2": { Country1: [ {name: "c", id: "3"}, {name: "d", id: "4"} ], Country2: [ {name: "e", id: "5"}, {name: "f", id: "6"} ] } }Me gustaría poder filtrar por cadena, país y nombre. Pero no estoy seguro de cómo filtrar más abajo que el nivel de la cadena. hasta ahora lo he intentado
const filteredChains = Object.entries(dict).filter( ([chain, countries]) => { if (searchQuery.length > 0) { return chain.includes(searchQuery); } else { return chain; } } ); searchQuery es la entrada de una barra de búsqueda que permite al usuario filtrar lo que se muestra. El usuario debe poder filtrar por cadena, país y nombre. Si el usuario escribe "j", esperaría que el resultado sea que solo se muestren las claves o los valores que contienen "j".
¿Es posible ampliar este para filtrar más abajo? ¿O estoy totalmente fuera?
reduce las entradas del objeto y, para cada clave/valor, introdúzcalas en una matriz temporal, y luego combine esa matriz con el acumulador para la siguiente iteración.
const dict={Chain1:{Country1:[{name:"a",id:"1"},{name:"b",id:"2"}]},Chain2:{Country1:[{name:"c",id:"3"},{name:"d",id:"4"}],Country2:[{name:"e",id:"5"},{name:"f",id:"6"}]}}; function search(searchQuery) { // Making sure that we match against lowercase letters searchQuery = searchQuery.toLowerCase(); if (searchQuery.length > 0) { // `reduce` over the object entries return Object.entries(dict).reduce((acc, [chain, country]) => { const temp = []; // If the chain key includes the query, // push it into the temp array if (chain.toLowerCase().includes(searchQuery)) { temp.push(chain); } const countryKey = Object.keys(country)[0]; // If the country key includes the query, // push it into the temp array if (countryKey.toLowerCase().includes(searchQuery)) { temp.push(countryKey); } const names = Object.values(country)[0].map(obj => obj.name); // `filter` out the objects under country that // match the query and... push them into the temp array const filteredNames = names.filter(name => { return name.toLowerCase().includes(searchQuery); }); temp.push(filteredNames); return [...acc, ...temp.flat()]; }, []); } return null; } console.log(search('a')); console.log(search('i')); console.log(search('c')); console.log(search(''));Supongo que desea recuperar el mismo objeto, solo con los países, que chocan con la consulta de búsqueda por nombre o identificación.
var dict = { Chain1: { Country1: [ { name: 'a', id: '1' }, { name: 'b', id: '2' }, ], }, Chain2: { Country1: [ { name: 'c', id: '3' }, { name: 'd', id: '4' }, ], Country2: [ { name: 'e', id: '5' }, { name: 'f', id: '6' }, ], }, }; function filter(dict, searchQuery){ if(!dict) return null; if(!searchQuery || searchQuery.length <=0) return dict; const result = {}; for (chainKey in dict) { if (dict.hasOwnProperty(chainKey)) { const chains = dict[chainKey]; for (countryKey in chains) { if (chains.hasOwnProperty(countryKey)) { const countries = chains[countryKey]; const filteredCountries = countries.filter( (country) => country.name.includes(searchQuery) || country.id.includes(searchQuery) ); if (filteredCountries.length) { result[chainKey] = {}; result[chainKey][countryKey] = filteredCountries; } } } } } return result; } console.log(filter(dict, "a")); console.log(filter(dict, "e")); console.log(filter(dict, "f"));