0

I'm trying to search inside an object array to see if any object contains the object I'm looking for and assign it to a variable.

This is the interface that I'm using. Basically I have an array of countries, each of which has it's own array of cities.

import { ICity } from "./city";

export interface ICountry {
    name: string,
    capital: string,
    language: string,
    population: number,
    density: number,
    area: number,
    majorCities: ICity[]
}

The object I'm looking for is the city parameter of this function, but it always returns undefined. What is the best way to find country which a certain city belongs to?

remove(city: ICity): void {
    var country;
    this.countries.forEach(cn => {
      if (cn.majorCities.includes(city)) {
        country = cn;
        console.log(cn);
      }
    });
    console.log(country);
  }
fab680
  • 39
  • 5
  • is `ICity` an object? If so you can't use `includes` unless you are looking for strict reference equality. You will need to look for a matching property of `city` either in a `find()`, `findIndex()` call, or if you just want to establish if it exists in the array you can use `some()`. ie. `if (cn.majorCities.some(c => c.name === city.name)) {...` – pilchard Jan 09 '22 at 13:43
  • 1
    Does this answer your question? [How to determine if Javascript array contains an object with an attribute that equals a given value?](https://stackoverflow.com/questions/8217419/how-to-determine-if-javascript-array-contains-an-object-with-an-attribute-that-e) – pilchard Jan 09 '22 at 13:52

3 Answers3

1

The best way (in my opinion) is to store country id in city so you can find it easier.

But in this case you can do it like below:

remove(city: ICity): void {
  var country;
  this.countries.forEach((cn) => {
    if (cn.majorCities.find(c => c.toLowerCase() === city.toLowerCase())) {
      country = cn;
      console.log(cn);
    }
  });
  console.log(country);
}
Mahdi Zarei
  • 5,644
  • 7
  • 24
  • 54
1

Your ICity type object is not just a simple string I assume, so a check like:

if (cn.majorCities.includes(city)) 

would just return true if one of majorCities elements is the actual instance referenced via the city variable.

As your ICity interface surely consists of something like a name property e.g.

interface ICity {
name: string
}

you should check for such a string-type property.

if (cn.majorCities.some((el) => {
        return el.name == city.name

    })) {
    // do something
}
obscure
  • 11,916
  • 2
  • 17
  • 36
1

You should do like below

const countries = [{
    name: 'Iran',
    cities: ['Shiraz', 'Tehran']
  },
  {
    name: 'Germay',
    cities: ['Berlin']
  }
]

const findCity = (city) => {
  countries.forEach(country => {
    if (country.cities.includes(city))
      console.log(city, 'has founded!')

  })
}
findCity('Shiraz')
Ahmad
  • 816
  • 2
  • 9
  • 15