Search code examples
javascriptarraysjavascript-objects

Javascript: Find matching property value in deeply nested arrays and objects


I need to match values from two JSON sources. Using the javascript find method this way works for me when the nesting of the "cities" array is one level more shallow (just an array of objects), but it's not working with deeper nesting (an array of objects within an array of objects).

Essentially, what I am trying to do is loop through the feeds[0].feed.details.place array and find the matching cities.CountyPlaces.PlaceFIPSCode value for each. I actually need the entire "place" object, so I can utilize any data within for each match.

// console.log(feeds[0].feed.details.place);
// console.log(cities[1].CountyPlaces[2].PlaceName);
feeds[0].feed.details.place.map(async (arrItem, z) => {
  // console.log('arrItem: ', arrItem);
  const cityMatch = await cities.find((cityObject, i) => {
    // console.log(i, 'cityObject: ', cityObject);
    arrItem === cityObject.PlaceName;
  });
  if (cityMatch !== undefined) {
    // --> THIS IS WHERE I NEED TO MANIPULATE MATCHING DATA
    console.log(
      z,
      'cityMatch: ',
      arrItem,
      cityMatch.PlaceName,
      cityMatch.PlaceFIPSCode
    );
  } else {
    // there should be a defined match for every "place" and no else results
    console.log(z, '💥 cityMatch UNDEFINED', arrItem);
  }
});

Here is a simplified example of the data I am using, with identical nesting:

const feeds = [
  {
    feed: {
      record: '0002',
      details: {
        county: ['Alameda'],
        place: ['Alameda', 'Berkeley', 'Oakland'],
      },
    },
  },
];
const cities = [
  {
    CountyName: 'San Francisco',
    CountyFIPSCode: '075',
    CountyPlaces: [
      {
        PlaceName: 'San Francisco',
        PlaceFIPSCode: '67000',
      },
    ],
  },
  {
    CountyName: 'Alameda',
    CountyFIPSCode: '001',
    CountyPlaces: [
      {
        PlaceName: 'Alameda',
        PlaceFIPSCode: '00562',
      },
      {
        PlaceName: 'Albany',
        PlaceFIPSCode: '00674',
      },
      {
        PlaceName: 'Berkeley',
        PlaceFIPSCode: '06000',
      },
      {
        PlaceName: 'Emeryville',
        PlaceFIPSCode: '22594',
      },
      {
        PlaceName: 'Oakland',
        PlaceFIPSCode: '53000',
      },
    ],
  },
];

Solution

  • You can filter the cities array based on the CountyName matching details.county[0], then filter the CountyPlaces of the matching city based on the PlaceName being in details.place:

    const feeds = [
      {
        feed: {
          record: '0002',
          details: {
            county: ['Alameda'],
            place: ['Alameda', 'Berkeley', 'Oakland'],
          },
        },
      },
    ];
    
    const cities = [
      {
        CountyName: 'San Francisco',
        CountyFIPSCode: '075',
        CountyPlaces: [
          {
            PlaceName: 'San Francisco', PlaceFIPSCode: '67000',
          },
        ],
      },
      {
        CountyName: 'Alameda',
        CountyFIPSCode: '001',
        CountyPlaces: [
          {
            PlaceName: 'Alameda', PlaceFIPSCode: '00562',
          },
          {
            PlaceName: 'Albany', PlaceFIPSCode: '00674',
          },
          {
            PlaceName: 'Berkeley', PlaceFIPSCode: '06000',
          },
          {
            PlaceName: 'Emeryville', PlaceFIPSCode: '22594',
          },
          {
            PlaceName: 'Oakland', PlaceFIPSCode: '53000',
          },
        ],
      },
    ];
    
    const county = feeds[0].feed.details.county[0];
    const places = feeds[0].feed.details.place;
    
    const result = cities
      .filter(city => city.CountyName == county)[0]
      .CountyPlaces.filter(({ PlaceName }) => places.includes(PlaceName))
      
    console.log(result)