Фильтр JavaScript с рекурсивными отношениями

Мой вариант использования примерно такой.

  • У меня есть массив объектов, называемых местоположениями.
  • Он содержит информацию о провинциях, районах и городах.
  • Город принадлежит району, район принадлежит провинции.
  • Если parent_region_idnull значит это провинция.
  • Если parent_region_id - это идентификатор провинции, значит, это район.
  • Иначе это город.

Моя цель - отфильтровать все города из массива. Я сделал странный способ, и он работает.

Но я хотел бы знать, что является наиболее оптимальным способом сделать это? Это мой рабочий код.

const locations = [
{id:1,name:"Western province",parent_region_id:null},
{id:2,name:"Southern province",parent_region_id:null},
{id:3,name:"Central province",parent_region_id:null},
{id:4,name:"Colombo district",parent_region_id:1},
{id:5,name:"Galle district",parent_region_id:2},
{id:6,name:"Kandy district",parent_region_id:3},
{id:7,name:"Maharagama",parent_region_id:4},
{id:8,name:"Nugegoda",parent_region_id:4},
{id:9,name:"Peradeniya",parent_region_id:6},
]

//get the province ids first

const provinces = []

locations.forEach(e=> {
if (!e.parent_region_id){
  provinces.push(e.id)
}
})

// get all the districts then

const districts = []

locations.forEach(e=>{
  if (provinces.includes(e.parent_region_id)){
  districts.push(e.id) 
  }
})


//get cities

const cities = [];


locations.forEach(e=> 
{
  if (!districts.includes(e.id) && !provinces.includes(e.id)){
    console.info(e.name," is a city")
  }
})
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Используйте Массив # фильтр и Массив # найти.

const locations=[{id:1,name:"Western province",parent_region_id:null},{id:2,name:"Southern province",parent_region_id:null},{id:3,name:"Central province",parent_region_id:null},{id:4,name:"Colombo district",parent_region_id:1},{id:5,name:"Galle district",parent_region_id:2},{id:6,name:"Kandy district",parent_region_id:3},{id:7,name:"Maharagama",parent_region_id:4},{id:8,name:"Nugegoda",parent_region_id:4},{id:9,name:"Peradeniya",parent_region_id:6},]

const res = locations.filter(({id, parent_region_id},i,a)=>{
  if (!parent_region_id) return false;
  const loc = a.find(l=>l.id === parent_region_id);
  return !loc.parent_region_id ? false : true;
});

console.info(res);

Решение путем удаления провинций сначала:

const locations=[{id:1,name:"Western province",parent_region_id:null},{id:2,name:"Southern province",parent_region_id:null},{id:3,name:"Central province",parent_region_id:null},{id:4,name:"Colombo district",parent_region_id:1},{id:5,name:"Galle district",parent_region_id:2},{id:6,name:"Kandy district",parent_region_id:3},{id:7,name:"Maharagama",parent_region_id:4},{id:8,name:"Nugegoda",parent_region_id:4},{id:9,name:"Peradeniya",parent_region_id:6},]

const res = locations
.filter(({parent_region_id})=>parent_region_id!==null)
.filter(({parent_region_id},i,a)=>{
  return a.findIndex(l=>l.id === parent_region_id) > -1;
});

console.info(res);

Если вы хотите сделать код чище и компактнее, попробуйте использовать filter() следующим образом:

 

const locations = [
{id:1,name:"Western province",parent_region_id:null},
{id:2,name:"Southern province",parent_region_id:null},
{id:3,name:"Central province",parent_region_id:null},
{id:4,name:"Colombo district",parent_region_id:1},
{id:5,name:"Galle district",parent_region_id:2},
{id:6,name:"Kandy district",parent_region_id:3},
{id:7,name:"Maharagama",parent_region_id:4},
{id:8,name:"Nugegoda",parent_region_id:4},
{id:9,name:"Peradeniya",parent_region_id:6},
];

const provinces = locations.filter(e => !e.parent_region_id);

const districts = locations.filter(e => provinces.some(p => p.id == e.parent_region_id));

const cities = locations.filter(e => !provinces.includes(e) && !districts.includes(e));

console.info(provinces);
console.info(districts);
console.info(cities);

Другие вопросы по теме