1

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.

1
  • What defines "unique" in your case? Commented Feb 18, 2022 at 10:54

2 Answers 2

1

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; }

A slightly shorter approach

You could get an object of grouped objects by code, with either the index or false, take the values as indices array and filter the data by having a look to the indices array.

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" }] }],
    indices = Object.values(data.reduce((r, o, i) => {
        o.currencies.forEach(({ code }) => r[code] = !(code in r) && i);
        return r;
    }, {})),
    result = data.filter((_, i) => indices.includes(i));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

1

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}

2 Comments

please try with my data set.
@NinaScholz Thank you for pointing that out, I hope I squashed all bugs now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.