Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

1.9K
Vistas
Angular/RXJS, ¿cómo clasifico una matriz observable de objetos en función de un valor de cadena ESPECÍFICO?

Tengo un problema interesante (creo) y me encantaría recibir ayuda.

Estoy devolviendo un Observable[DisplayCard[]] que se filtra en función de un valor. Todo eso funciona muy bien. Después de filtrar esa matriz en función de un valor, AHORA quiero ordenar la matriz devuelta por otro de sus valores llamado category . category solo puede ser uno de los tres valores de cadena: ONGOING , UPCOMING y PAST .

Quiero devolver una matriz que se ordenará así: EN CURSO --> PRÓXIMO --> PASADO. Entonces, todas las tarjetas de visualización que tienen "EN CURSO" estarán al frente, después de que no haya más de esas, quiero todas las tarjetas "Próximas" y luego, después de esas, quiero que se muestren todas las tarjetas "PASADAS".

Aquí está mi código:

 displayCommunityCards$ = this.cardService.displayCards$ .pipe( map(communityEventsCards => communityEventsCards.filter(community => community.type === 'COMMUNITY EVENT') .sort((a, b) => { return ??? }), tap(data => console.log('Community Cards: ', JSON.stringify(data))), );
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Simplemente puede hacer esto creando tres matrices y combinándolas en orden. Se puede hacer en O(n).

 const upcoming = [], past = [], ongoing = []; const events = [{event: "upcoming", id: 1}, {event: "upcoming", id: 2}, {event: "past", id: 3}, {event: "past", id: 4}, {event: "ongoing", id: 5}]; events.forEach(el => { el.event === "upcoming" ? upcoming.push(el) : el.event === "past" ? past.push(el) : el.event === "ongoing" ? ongoing.push(el) : false; }); console.log([...ongoing, ...upcoming, ...past]);

En el fragmento anterior, la memoria utilizada será más.

Quiero devolver una matriz que se ordenará así: EN CURSO --> PRÓXIMO --> PASADO. Entonces, todas las tarjetas de visualización que tienen "EN CURSO" estarán al frente, después de que no haya más de esas, quiero todas las tarjetas "Próximas" y luego, después de esas, quiero que se muestren todas las tarjetas "PASADAS".

Otra forma interesante podría ser crear claves en un objeto con "en curso", "próximo" y "pasado". Puede crear una matriz como valor para cada uno y empujar las cosas una vez que lo encuentre. Debe verificar cuándo comenzar a mostrar los próximos eventos y cuándo comenzar a pasar.

 const result = { upcoming: [], past: [], ongoing: [] } const events = [{event: "upcoming", id: 1}, {event: "upcoming", id: 2}, {event: "past", id: 3}, {event: "past", id: 4}, {event: "ongoing", id: 5}]; events.forEach(el => { el.event === "upcoming" ? result.upcoming.push(el) : el.event === "past" ? result.past.push(el) : el.event === "ongoing" ? result.ongoing.push(el) : false; }); console.log(result);

Cuando haya terminado, simplemente tome la clave y arroje los datos a la vista.

over 4 years ago · Santiago Trujillo Denunciar

0

Si bien la otra respuesta funciona, no necesita crear varias matrices o incluso suscribirse para lograr esto. Siempre es mejor usar tuberías asíncronas en su plantilla y proporcionar la función de clasificación para usar en el resultado de las tuberías asíncronas.

El Enum & Interface utilizado en este ejemplo:

 enum Cat { ONGOING = 'ONGOING', UPCOMING = 'UPCOMING', PAST = 'PAST', } interface DisplayCommunityCards { category: Cat; type: string; }

En su componente:

 cards$ = of([ { category: Cat.ONGOING, type: 'COMMUNITY EVENT' }, { category: Cat.PAST, type: 'COMMUNITY EVENT' }, { category: Cat.PAST, type: 'COMMUNITY EVENT' }, { category: Cat.UPCOMING, type: 'COMMUNITY EVENT' }, ]); displayCommunityCards$ = this.cards$.pipe( map((communityEventsCards) => communityEventsCards.filter( (community) => community.type === 'COMMUNITY EVENT' ) ) ); sort( displayCommunityCards: DisplayCommunityCards[] ): DisplayCommunityCards[] { const catOrder = Object.values(Cat); return displayCommunityCards.sort((a, b) => { return catOrder.indexOf(a.category) - catOrder.indexOf(b.category); }); }

(cards$ es solo un reemplazo del observable que obtiene de su servicio).

En tu plantilla:

 <p *ngFor="let c of sort(displayCommunityCards$ | async)" > {{ c.category }} </p>

Al hacerlo de esta manera, no tendrá que preocuparse por darse de baja en un onDestroy y podrá utilizar la estrategia OnPush ChangeDetectionStrategy.

Aquí hay un ejemplo en Stackblitz .

over 4 years ago · Santiago Trujillo Denunciar

0

Puede lograr esto creando una enumeración para representar todos los valores posibles para CardCategory y definiendo el orden en que deben ordenarse usando Record<CardCategory, number> :

 export enum CardCategory { OnGoing = 'ONGOING', Upcoming = 'UPCOMING', Past = 'PAST', } export const CategorySortOrder: Record<CardCategory, number> = { 'ONGOING' : 0, 'UPCOMING' : 1, 'PAST' : 2 }

Luego crea una función de clasificación que use eso para ordenar:

 function sortByCardCategory(a: DisplayCard, b: DisplayCard) { if(a.category === b.category) return 0; return CategorySortOrder[a.category] > CategorySortOrder[b.category] ? 1 : -1; }

Ahora puede ordenar fácilmente así:

 displayCommunityCards$ = this.cardService.displayCards$.pipe( map(cards => cards .filter(c => c.type === CardType.CommunityEvent) .sort(sortByCardCategory) ) );

Aquí hay una demostración de StackBlitz en funcionamiento.


El uso del tipo Record no es completamente necesario, pero garantiza que defina un orden de clasificación para todos los valores de CardCategory . Por ejemplo, si agregó una nueva CardCategory , TypeScript arrojará un error sobre CategorySortOrder que no define todos los valores de CardCategory .

captura de pantalla del error

 Property 'MYNEWCAT' is missing in type '{ UPCOMING: number; ONGOING: number; PAST: number; }' but required in type 'Record<CardCategory, number>'. (2741)
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda