【问题标题】:Sort and group objects alphabetically by the first letter from an array in Angular?按Angular中数组的第一个字母按字母顺序对对象进行排序和分组?
【发布时间】:2021-02-18 01:58:33
【问题描述】:

如何按角度数组中的第一个字母按字母顺序对对象进行排序和分组?我已经看到了在Javascript 中按字母顺序对对象进行排序和分组的示例,以及我在 Angular 中查看的确切答案和输出 json。

截至目前我的 api json 就像this stackblitz

expexted api json 想要this stackblitz

我已经尝试过了,但我无法找到角度的解决方案。

真正的 Json:

employees = [
  { name: "Abigail", age: "25" },
  { name: "Axle", age: "29" },
  { name: "Brianna", age: "25" },
  { name: "Brooklyn", age: "23" },
  { name: "Camila", age: "24" },
  { name: "Charlotte", age: "28" },
  { name: "David", age: "22" }
];

在按数组中的第一个字母按字母顺序对对象进行排序和分组后,期望 json 像:

[
  {
    "alphabet": "A",
    "record": [
      { "name": "Abigail", "age": "25" },
      { "name": "Axle", "age": "29" }
    ]
  },
  {
    "alphabet": "B",
    "record": [
      { "name": "Brianna", "age": "25" },
      { "name": "Brooklyn", "age": "23" }
    ]
  },
  {
    "alphabet": "C",
    "record": [
      { "name": "Camila", "age": "24" },
      { "name": "Charlotte", "age": "28" }
    ]
  },
  {
    "alphabet": "D", "record": [
      { "name": "David", "age": "22" }
    ]
  }
]

预期输出如下:

A
Abigail
Axle
B
Brianna
Brooklyn
C
Camila
Charlotte
D
David

【问题讨论】:

  • 没有 Typescript 特定的排序方法。 TS 是 Javascript 的超集。所以所有有效的 JS 也应该是有效的 TS。
  • 感谢您的评论,如果可能,请更新 stacblitz 以获得更好的理解。谢谢

标签: arrays json angular typescript sorting


【解决方案1】:

正如评论中提到的,没有特定于 Typescript 的方法来对数据进行排序和分组。您可以使用 JS Array#reduce 将对象分组到您的要求。

试试下面的

const employees = [ { name: "Abigail", age: "25" }, { name: "Axle", age: "29" }, { name: "Brianna", age: "25" }, { name: "Brooklyn", age: "23" }, { name: "Camila", age: "24" }, { name: "Charlotte", age: "28" }, { name: "David", age: "22" } ];

const output = employees
  .reduce((acc, curr) => {
    const idx = acc.findIndex(e => e.alphabet === curr.name[0]);
    if (idx === -1) {
      acc.push({ alphabet: curr.name[0], record: [curr] });
    }
    else {
      acc[idx].record.push(curr); 
      acc[idx].record.sort((r1, r2) => r1.name > r2.name ? 1 : -1);
    }
    return acc;
  }, [])
  .sort((e1, e2) => e1.alphabet > e2.alphabet ? 1 : -1);

console.log(output);

看起来就像是在 Stackblitz 中。

export class ExpansionOverviewExample {
  @ViewChild(MatAccordion, { static: false }) accordion: MatAccordion;

  employees = [
    { name: "Brianna", age: "25" },
    { name: "Axle", age: "29" },
    { name: "David", age: "22" },
    { name: "Brooklyn", age: "23" },
    { name: "Camila", age: "24" },
    { name: "Abigail", age: "25" },
    { name: "Charlotte", age: "28" }
  ];

  constructor() {
    this.employees = this.employees
      .reduce((acc, curr) => {
        const idx = acc.findIndex(e => e.alphabet === curr.name[0]);
        if (idx === -1) {
          acc.push({ alphabet: curr.name[0], record: [curr] });
        } else {
          acc[idx].record.push(curr);
          acc[idx].record.sort((r1, r2) => (r1.name > r2.name ? 1 : -1));
        }
        return acc;
      }, [])
      .sort((e1, e2) => (e1.alphabet > e2.alphabet ? 1 : -1));
  }
}

您还可以在模板中使用安全导航运算符?.,这样您就不会在reduce 完成之前收到任何undefined 错误。

<div *ngFor="let mani of employees">
    <div>
        <p>{{mani?.alphabet}}</p>
        <p *ngFor="let group of mani?.record"> {{ group?.name }}</p>
        <hr>
    </div>
</div>

我已经更新了你的Stackblitz

【讨论】:

    猜你喜欢
    • 2018-12-03
    • 2017-02-28
    • 1970-01-01
    • 2019-06-15
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    相关资源
    最近更新 更多