I am trying to filter out countries in an array of objects with unique currency. The country
array structure is
[
{
country: "A",
currencies: [{code: "USD"}, {code: "EURO"}]
},
{
country: "B",
currencies: [{code: "AFN"}]
},
{
country: "C",
currencies: [{code: "CND"}, {code: "EURO"}]
},
{
country: "D",
currencies: [{code: "USD"}]
}
]
What I'm trying to achieve is to filter the country
array such that the output array contains only countries with unique value like
[
{
country: "B",
currencies: [{code: "AFN"}]
},
{
country: "C",
currencies: [{code: "CND"}, {code: "EURO"}]
}
]
The countries A
and D
have both non-unique currency values. In case of country C
, even though EURO
is non unique, it's other currency code CND
is an unique value. I had used array filter method but couldn't find a solution. Any help is appreciated.
CodePudding user response:
You could get an object of grouped objects by code
, get only the arrays with a single item, flat the result and get only unique objects as result.
const
data = [{ country: "A", currencies: [{ code: "USD" }, { code: "EURO" }] }, { country: "B", currencies: [{ code: "AFN" }] }, { country: "C", currencies: [{ code: "CND" }, { code: "xEURO" }, { code: "EURO" }] }, { country: "D", currencies: [{ code: "USD" }] }],
result = Object
.values(data.reduce((r, o) => {
o.currencies.forEach(({ code }) => (r[code] ??= []).push(o));
return r;
}, {}))
.filter(a => a.length === 1)
.flat()
.filter((s => o => !s.has(o) && s.add(o))(new Set));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
You can use a dictionary code -> country
and check, whether code
has been set previously. If it has, then the currency is not unique to one country; otherwise it is.
Because I marked non-unique currencies with null, I have to filter them, which I do with Boolean()
.
const data = [
{ country: "A", currencies: [{ code: "USD" }, { code: "EURO" }] },
{ country: "B", currencies: [{ code: "AFN" }] },
{ country: "C", currencies: [{ code: "CND" }, { code: "xEURO" }, { code: "EURO" }] },
{ country: "D", currencies: [{ code: "USD" }] }
];
console.log(getByUniqueCurrencies(data));
function getByUniqueCurrencies(countries) {
const matchingCountries = Object.values(
countries.reduce((r, country) => {
country.currencies.forEach(
({ code }) => r[code] = r[code] === undefined ? country : null
);
return r;
}, {})
).filter(Boolean);
return Array.from(new Set(matchingCountries)); // Remove duplicates
}
.as-console-wrapper{max-height:100%!important}