与C#LINQ GroupBy等效的Typescript是什么?

时间:2017-12-07 22:08:24

标签: javascript arrays angular typescript

我正在使用带有Typescript的Angular。我有多个属性的对象数组。我已将它们分组在服务器端代码中并设置了重复属性。当用户更新列表时,我必须遍历列表并在客户端查找重复项。在Typescript中是否有C#LINQ GroupBy等价物?

这是我的C#LINQ代码:

listMP.Where(item => item.Type == "Other").GroupBy(i => new { i.Type, i.Name, i.Address1, i.City }).Where(g => g.Count() > 1)
.SelectMany(g=>g.Select(gg =>gg.Id));

5 个答案:

答案 0 :(得分:1)

有一个用于LINQ的TypeScript库。

它称为 ts-generic-collections-linq

提供强类型的可查询集合,例如:

  • 列表
  • 字典

易于使用。

NPM

https://www.npmjs.com/package/ts-generic-collections-linq

样本linq查询:

//query to get owners by the sex/gender of their pets
let ownersByPetSex = owners.join(pets, owner => owner.id, pet => pet.ownerId, (x, y) => new OwnerPet(x,y))
                           .groupBy(x => [x.pet.sex])
                           .select(x =>  new OwnersByPetSex(x.groups[0], x.list.select(x => x.owner)));

答案 1 :(得分:0)

  

与C#LINQ GroupBy相当的Typescript是什么?

您可以使用Array.prototype.reduce:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

或者,您可以使用lodash groupByhttps://lodash.com/docs/4.17.4#groupBy

答案 2 :(得分:0)

我正在使用一个用Typescript编写的小型“类似于Linq的”库,该库可以与数组和Angular 8或更高版本一起用于我的业余项目。 (目前尚不建议将其用于商业用途,但它可能会激发其他人为Typescript制作一个完全成熟的Linq类库)。 Array-extensions.ts on Github

可以传入分组功能,因此您可以定义如何对具有多个属性的对象数组进行分组。这是我使用Angular 8和Typescript的方法。

首先,在array-extensions.ts文件中定义以下内容:

  export { } //creating a module of below code
    declare global {
  type predicate<T> = (arg: T) => boolean;
  type sortingValue<T> = (arg: T) => any;
  interface Array<T> {
    GroupBy<T>(groupFunc: (arg: T) => string): any[];
  }
}

    if (!Array.prototype.GroupBy) {
  Array.prototype.GroupBy = function <T>(groupFunc: (arg: T) => string): any[] {
    let groups: any = {};
    this.forEach(el => {
      let itemKeyValue: any = groupFunc(el);
      if (itemKeyValue in groups === false) {
        groups[itemKeyValue] = [];
      }
      groups[itemKeyValue].push(el);
    });
    let result = Object.keys(groups).map(key => {
      return {
        key: key,
        values: groups[key]
      }
    });
    return result;
  }
}

我们现在可以将这样的对象数组归为一个组件的构造函数。

this.groupedMoviesWithJarJarBinks = StarWarsMovies.GroupBy<Movie>(movie =>
  movie.main_characters.indexOf('Jar Jar Binks') >= 0 ? "Movie starring JarJar" : "Movie not starring JarJar");

以下是一些示例数据:

    import { Movie } from './movie';

export const StarWarsMovies : Array<Movie> =
 [{
      "title" : "Star Wars: Episode I - The Phantom Menace",
      "episode_number" : "1",
      "main_characters" : ["Qui-Gon Jinn", "Obi-Wan Kenobi", "Anakin Skywalker", "Padmé Amidala", "Jar Jar Binks", "Darth Maul"],
      "description" : "The evil Trade Federation, led by Nute Gunray is planning to take over the peaceful world of Naboo. Jedi Knights Qui-Gon Jinn and Obi-Wan Kenobi are sent to confront the leaders. But not everything goes to plan. The two Jedi escape, and along with their new Gungan friend, Jar Jar Binks head to Naboo to warn Queen Amidala, but droids have already started to capture Naboo and the Queen is not safe there. Eventually, they land on Tatooine, where they become friends with a young boy known as Anakin Skywalker. Qui-Gon is curious about the boy, and sees a bright future for him. The group must now find a way of getting to Coruscant and to finally solve this trade dispute, but there is someone else hiding in the shadows. Are the Sith really extinct? Is the Queen really who she says she is? And what's so special about this young boy?",
      "poster" : "star_wars_episode_1_poster.png",
      "hero_image" : "star_wars_episode_1_hero.jpg"
    },

    {
      "title" : "Star Wars: Episode II - Attack of the Clones",
      "episode_number" : "2",
      "main_characters" : ["Obi-Wan Kenobi", "Anakin Skywalker", "Count Dooku", "Padmé Amidala", "Mace Windu", "Yoda", "Jango Fett", "Supreme Chancellor Palpatine"],
      "description" : "Ten years after the 'Phantom Menace' threatened the planet Naboo, Padmé Amidala is now a Senator representing her homeworld. A faction of political separatists, led by Count Dooku, attempts to assassinate her. There are not enough Jedi to defend the Republic against the threat, so Chancellor Palpatine enlists the aid of Jango Fett, who promises that his army of clones will handle the situation. Meanwhile, Obi-Wan Kenobi continues to train the young Jedi Anakin Skywalker, who fears that the Jedi code will forbid his growing romance with Amidala.",
      "poster" : "star_wars_episode_2_poster.png",
      "hero_image" : "star_wars_episode_2_hero.jpg"
    },

    {
      "title" : "Star Wars: Episode III - Revenge of the Sith",
      "episode_number" : "3",
      "main_characters" : ["Obi-Wan Kenobi", "Anakin Skywalker", "Count Dooku", "Padmé Amidala", "Mace Windu", "Yoda", "C-3PO", "Supreme Chancellor Palpatine"],
      "description" : "Three years after the onset of the Clone Wars; the noble Jedi Knights are spread out across the galaxy leading a massive clone army in the war against the Separatists. After Chancellor Palpatine is kidnapped, Jedi Master Obi-Wan Kenobi and his former Padawan, Anakin Skywalker, are dispatched to eliminate the evil General Grievous. Meanwhile, Anakin's friendship with the Chancellor arouses suspicion in the Jedi Order, and dangerous to the Jedi Knight himself. When the sinister Sith Lord, Darth Sidious, unveils a plot to take over the galaxy, the fate of Anakin, the Jedi order, and the entire galaxy is at stake. Upon his return, Anakin Skywalker's wife Padme Amidala is pregnant, but he is having visions of her dying in childbirth. Anakin Skywalker ultimately turns his back on the Jedi, thus completing his journey to the dark side and his transformation into Darth Vader. Obi-Wan Kenobi must face his former apprentice in a ferocious lightsaber duel on the fiery world of Mustafar.",
      "poster" : "star_wars_episode_3_poster.png",
      "hero_image" : "star_wars_episode_3_hero.jpg"
    },

    {
      "title" : "Star Wars: Episode IV - A New Hope",
      "episode_number" : "4",
      "main_characters" : ["Luke Skywalker", "Han Solo", "Princess Leia Organa", "Ben Kenobi", "Darth Vader", "C-3P0", "R2-D2", "Chewbacca"],
      "description" : "Part IV in George Lucas' epic, Star Wars: A New Hope opens with a Rebel ship being boarded by the tyrannical Darth Vader. The plot then follows the life of a simple farm boy, Luke Skywalker, as he and his newly met allies (Han Solo, Chewbacca, Obi-Wan Kenobi, C-3PO, R2-D2) attempt to rescue a Rebel leader, Princess Leia, from the clutches of the Empire. The conclusion is culminated as the Rebels, including Skywalker and flying ace Wedge Antilles make an attack on the Empire's most powerful and ominous weapon, the Death Star.",
      "poster" : "star_wars_episode_4_poster.png",
      "hero_image" : "star_wars_episode_4_hero.jpg"
    },

    {
      "title" : "Star Wars: Episode V - The Empire Strikes Back",
      "episode_number" : "5",
      "main_characters" : ["Luke Skywalker", "Han Solo", "Princess Leia Organa", "Darth Vader", "C-3P0", "R2-D2", "Chewbacca", "Lando Calrissian", "Boba Fett"],
      "description" : "Fleeing the evil Galactic Empire, the Rebels abandon their new base in an assault with the Imperial AT-AT walkers on the ice world of Hoth. Princess Leia, Han Solo, Chewbacca and the droid C-3PO escape in the Millennium Falcon, but are later captured by Darth Vader on Bespin. Meanwhile, Luke Skywalker and the droid R2-D2 follows Obi-Wan Kenobi's posthumous command, and receives Jedi training from Master Yoda on the swamp world of Dagobah. Will Skywalker manage to rescue his friends from the Dark Lord?",
      "poster" : "star_wars_episode_5_poster.png",
      "hero_image" : "star_wars_episode_5_hero.jpg"
    },    
    {
      "title" : "Star Wars: Episode VI - Return of the Jedi",
      "episode_number" : "6",
      "main_characters" : ["Luke Skywalker", "Han Solo", "Princess Leia Organa", "Darth Vader", "C-3P0", "Chewbacca", "The Emperor", "Boba Fett"],
      "description" : "Darth Vader and the Empire are building a new, indestructible Death Star. Meanwhile, Han Solo has been imprisoned, and Luke Skywalker has sent R2-D2 and C-3PO to try and free him. Princess Leia - disguised as a bounty hunter - and Chewbacca go along as well. The final battle takes place on the moon of Endor, with its natural inhabitants, the Ewoks, lending a hand to the Rebels. Will Darth Vader and the Dark Side overcome the Rebels and take over the universe?",    
    "poster" : "star_wars_episode_6_poster.png",
          "hero_image" : "star_wars_episode_6_hero.jpg"
        }];

电影类如下:

    export class Movie {
  title: string;
  episode_number: string;
  main_characters: string[];
  description: string;
  poster: string;
  hero_image: string;
}

这使我们可以使用Typescript将数组分组,其语法与C#和Linq非常相似。

答案 3 :(得分:0)

我创建了一个新的现代化的 TypeScript LINQ库,名为sharp-collections。它支持所有.NET LINQ方法以及更多其他方法(包括groupBy)。它具有延迟执行(延迟执行),ForOf循环兼容性等功能。此处更多信息:https://github.com/vdolek/sharp-collections

import { Enumerable } from 'sharp-collections';

const data = [
  { name: 'Martin', sex: 'M', age: 28 },
  { name: 'Jane', sex: 'F', age: 27 },
  { name: 'Thomas', sex: 'M', age: 15 },
  { name: 'William', sex: 'M', age: 78 },
  { name: 'Kelly', sex: 'F', age: 30 },
];

const enumerable = Enumerable.from(data); // or List.from(data)

const adults = enumerable.where(x => x.age >= 18);
const adultsGroupedBySex = adults.groupBy(x => x.sex); // nothing is executed so far

// use any collection (Enumerable, List, ...) in ForOf cycle
for (const group of adultsGroupedBySex) {
  console.debug(`Sex: ${group.key}, count: ${group.count()}`);
}

// converts Enumerable to List
const adultsGroupedBySexList = adultsGroupedBySex.toList(); // or toReadOnlyList()

// converts Enumerable to JS Array
const adultsGroupedBySexArray = adultsGroupedBySex.toArray();

答案 4 :(得分:0)

这样一个老问题,但恕我直言还没有给出简单的打字稿答案。

这是使用 reduce 在打字稿中完成 groupBy 的方式:

const grouped  = myArray
        .reduce(
            (g: { [id: string]: MyObject[] }, o: MyObject) => {
                g[o.FK] = g[p.FK] || []; //check if key allready exists, else init a new array
                g[o.FK].push(o);   //add item to array
                return g;     // be sure to return, or g will be undefined in next loop
            }, 
            {}    //a second parameter to the reduce function, important to init the returned object
        );
相关问题