Tengo una variedad de objetos que contienen países del mundo con información adicional, por ejemplo
countries = [ { flag: 'assets/flags/angola.svg', code: 'AGO', name: 'Angola', regions: [{ name: 'Luanda' }] }, { flag: 'assets/flags/albania.svg', code: 'ALB', name: 'Albania', regions: [{ name: 'Korça' }, { name: 'Tirana' }, { name: 'Gjirokastër' }] }...Quiero extraer tres de mis países favoritos en una nueva matriz mientras los elimino de la matriz original, así que termino con dos matrices, una para mis países favoritos y otra para el resto de los países.
Me las arreglé para lograr esto de la siguiente manera:
public createCountriesList(allCountries: Country[]) { let topCountries: Country[] = []; let restOfCountries: Country[]; allCountries.forEach((element) => { switch (element.code) { case 'HRV': topCountries.push(element); break; case 'AT': topCountries.push(element); break; case 'GER': topCountries.push(element); break; } }); restOfCountries = allCountries.filter((c) => { return !topCountries.includes(c); });}Funciona, pero me preguntaba si hay una forma más elegante de hacerlo.
Todo parece estar bien según yo... Obviamente necesitas dos arreglos, uno para los extraídos y el segundo para el resto de países.
Una cosa en la que podemos trabajar es en la caja del interruptor.
En lugar de cambiar el caso, puede usar la función .includes . Almacene el nombre de los países que desea extraer en una matriz.
const arr = ['HRV','AT','GR']ahora puedes hacer,
if(arr.includes(element.code)){ //push into new array } else{ //push into another } Una cosa más que puede hacer es guardar el resto de los países usando .filter restOfTheCountries Simplemente devuelva verdadero para los países que fallan en lo anterior, si es el caso.
Simplemente puede usar un filtro regular para dividir la matriz:
const isTop = ({code}) => ['HRV','AT','GR'].includes(code); const topCountries = allCountries.filter(isTop); const restOfCountries = allCountries.filter((contry) => !isTop(contry));De otra forma, puede agregar una propiedad que muestre si este país es el mejor o no, y filtrar por esta clave
const withTop = countries.map((e) => ({...e, top: ['AGO','AT','GR'].includes(e.code)})); // { // code: "AGO" // flag: "assets/flags/angola.svg" // name: "Angola" // regions: [{…}] // top: true // }Probablemente crearía una función genérica separada para dividir la matriz según los criterios (usando ts ya que eres)
const splitArray = <T>(array: Array<T>, matchFunction: (el: T) => boolean) => { const matching: T[] = [], nonMatching: T[] = [] array.forEach(el => matchFunction(el) ? matching.push(el) : nonMatching.push(el)) return [matching, nonMatching] }entonces puedes llamarlo con la matriz y una función
const [topCountries, restOfCountries] = splitArray(countries, c => ["HRV", "AT", "GER"].includes(c.code)) eso sería un poco más legible. una solución más elegante es extender Array con esa funcionalidad ( Array.prototype.split ) y luego usar countries.split(c => ["HRV", "AT", "GER"].includes(c.code))