简体   繁体   中英

Combining and sorting two different array for select

I have two sample strings like this.

const country = [{id:1, name:"Mexico"},
                {id:2, name: "Canada"},
                {id:3, name:"Italy"}];

const city = [{id:19, name: "Ottava",country:{id:2, name:"Canada"}},
              {id:23, name:"Roma",country:{id:3, name: "Italy}];

Then I combine these two array

var newArray = country.concat(city);

Later I use this array with select

<Select>
{newArray.map((i) => (
          <Option value={i.country ? i.country.id : i.id}>
            {i.name}
            {i.country && ", " + i.country.name}
          </Option>
        ))}
</Select>

I want to sort the options alphabetically (by country name). I tried many methods. However, I haven't found a solution that I can use without breaking the option values.

As a result, the output I want to get is as follows.

<Option value={2}>Canada</Option>
<Option value={2}>Ottova, Canada</Option>
<Option value={3}>Italy</Option>
<Option value={3}>Roma, Italy</Option>
<Option value={1}>Mexico</Option>

If you need to do it by the name property, just use localCompare(...) inside your sort function's callback and add necessary checks for country and name as well like so:-

 const country = [{id:1, name:"Mexico"}, {id:2, name: "Canada"}, {id:3, name:"Italy"}]; const city = [{id:19, name: "Ottava",country:{id:2, name:"Canada"}}, {id:23, name:"Roma",country:{id:3, name: "Italy"}}]; var newArray = country.concat(city); function comparator(a,b){ let first = a.country?.name?? a.name; let second = b.country?.name?? b.name; return first.localeCompare(second); } console.log(newArray.sort(comparator));

One approach is to map these arrays to objects with same properties including a txt property to use for render.

In the cityOpts array do the name/country concatenation.

Then in render they will all be the same structural format

 const country=[{id:1,name:"Mexico"},{id:2,name:"Canada"},{id:3,name:"Italy"}],city=[{id:19,name:"Ottava",country:{id:2,name:"Canada"}},{id:23,name:"Roma",country:{id:3,name:"Italy"}}]; const countryOpts = country.map(({id, name})=> ({id, country: name, txt: name})) const cityOpts = city.map(({id, name, country}) => ({id, country:country.name, txt: `${name}, ${country.name}`})) const newArray = [...countryOpts,...cityOpts].sort((a,b) => a.country.localeCompare(b.country)) console.log(newArray)

Render would be simplified to

<Select>
{newArray.map((i) => <Option value={i.id}>{i.txt}</Option> )}
</Select>

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