Thanks for your time reading.
I need to sort countries by Language or Continent, the user selects the option he wants in the buttons.
countries is an array of objects of each country that contain:
- languages is an array of objects, because each country can have more than one language
- continent is an object with the continent name
Complete example(countries array content):CodePudding user response:
First filter the data and then group it by continent using
reduce
and then loop over the arrays and create the desired JSX.You can refer the snippet below (type "s" in the input box):
const countries = [ { name: "India", continent: { name: "Asia" }, languages: [{ name: "Hindi" }, { name: "English" }, { name: "Marathi" }], }, { name: "Sri Lanka", continent: { name: "Asia" }, languages: [{ name: "Srilankan" }, { name: "Tamil" }], }, { name: "Spain", continent: { name: "Europe" }, languages: [{ name: "Spanish" }, { name: "English" }], }, { name: "Slovakia", continent: { name: "Europe" }, languages: [{ name: "English" }], }, ]; function App() { const [searchTerm, setSearchTerm] = React.useState(""); return ( <div> <input type="text" value={searchTerm} onChange={({ target }) => setSearchTerm(target.value)} /> {Object.entries( countries .filter((c) => c.name.toLowerCase().includes(searchTerm.toLowerCase()) ) .reduce((res, c) => { if (!res[c.continent.name]) { res[c.continent.name] = []; } res[c.continent.name].push(c); return res; }, {}) ).map(([continent, countries]) => ( <ul key={continent}> <li> <div>{continent}</div> <ul> {countries.map(({ name, languages }) => ( <li key={name}> <div>{name}</div> <ul> {languages.map(({ name }) => ( <li key={name}>{name}</li> ))} </ul> </li> ))} </ul> </li> </ul> ))} </div> ); } const root = ReactDOM.createRoot(document.getElementById("root")); root.render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <div id="root"></div>
Following is the portion of code from the above snippet that does the grouping:
Object.entries( countries .filter((c) => c.name.toLowerCase().includes(searchTerm.toLowerCase())) .reduce((res, c) => { if (!res[c.continent.name]) { res[c.continent.name] = []; } res[c.continent.name].push(c); return res; }, {}) );