Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

1.9K
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda