Búsqueda de sitios web

angular - Equivalente en Javascript a C# LINQ GroupBy


Esta es una pregunta de seguimiento a la siguiente pregunta:

Equivalente en Javascript a C# LINQ Select

Estamos usando Angular 2 + TypeScript:

Tengo un arreglo de objetos. Cada objeto en el arreglo incluye una propiedad llamada 'StudentType'.

Necesito ejecutar una consulta al estilo LINQ en C# que extraiga una lista de StudentType en el arreglo y el número de miembros del arreglo con ese tipo particular.

Aunque puedo hacer un bucle al estilo antiguo y hacer esto, me pregunto si hay una mejor manera de hacerlo, como lo que ofrece C# LINQ GroupBy.

Dado que estamos usando Angular 2, los líderes del proyecto no permiten el uso de JQuery.

Respuesta #1

Solo inventé algunos valores de studentType para pruebas, pero puedes usar Array.prototype.reduce() para iterar sobre cada elemento del array de entrada y agregar o manipular propiedades de un objeto acumulador.

let arr = [{
    studentType: 'freshman'
  },
  {
    studentType: 'senior'
  },
  {
    studentType: 'sophomore'
  },
  {
    studentType: 'freshman'
  },
  {
    studentType: 'junior'
  },
  {
    studentType: 'senior'
  },
  {
    studentType: 'sophomore'
  },
  {
    studentType: 'freshman'
  },
  {
    studentType: 'sophomore'
  },
  {
    studentType: 'freshman'
  }
];

let result = arr.reduce((prev, curr) => {
  isNaN(prev[curr.studentType]) ? prev[curr.studentType] = 1 : prev[curr.studentType]++;
  return prev;
}, {});

console.log(result);

Respuesta #2

Creé una función groupBy en TypeScript.

export interface Group {
  key: any;
  items: any[];
}

export interface GroupBy {
  keys: string[];
  thenby?: GroupBy;
}

export const groupBy = (array: any[], grouping: GroupBy): Group[] => {
  const keys = grouping.keys;
  const groups = array.reduce((groups, item) => {
    const group = groups.find(g => keys.every(key => item[key] === g.key[key]));
    const data = Object.getOwnPropertyNames(item)
      .filter(prop => !keys.find(key => key === prop))
      .reduce((o, key) => ({ ...o, [key]: item[key] }), {});
    return group
      ? groups.map(g => (g === group ? { ...g, items: [...g.items, data] } : g))
      : [
          ...groups,
          {
            key: keys.reduce((o, key) => ({ ...o, [key]: item[key] }), {}),
            items: [data]
          }
        ];
  }, []);
  return grouping.thenby ? groups.map(g => ({ ...g, items: groupBy(g.items, grouping.thenby) })) : groups;
};

Hice una demostración de ello en StackBlitz en

https://stackblitz.com/edit/typescript-ezydzv

Artículos relacionados