在Typescript的回调函数中对JSON中的数据分组

tjjdgumg  于 2023-03-09  发布在  TypeScript
关注(0)|答案(3)|浏览(110)

我需要编写一个groupBy函数,使用给定的函数对JSON数据中的人员进行分组。下面是接口和JSON数据:

interface Person {
    name: string;
    yearOfBirth: number;
    placeOfBirth: string;
}

const input: Person[] = [
    {
        name: "Andy",
        yearOfBirth: 1984,
        placeOfBirth: "New York",
    },
    {
        name: "John",
        yearOfBirth: 1995,
        placeOfBirth: "New York",
    },
    {
        name: "Bill",
        yearOfBirth: 1995,
        placeOfBirth: "Orlando",
    },
    {
        name: "Tim",
        yearOfBirth: 1989,
        placeOfBirth: "Witchita",
    },
];

下面是我到目前为止的代码,它还没有接近工作,因为它应该,但我是新的回调函数,所以我一直试图得到它是如何工作的感觉。

const groupBy = (input: Person[], func: (p: Person) => string): string[] => {

    let collect: string[] = [];
    for (let i = 0; i < input.length; i++) {
        collect[i] = func(input[i]);

    }
    return collect;
}

try {
    console.log(groupBy(input, (p: Person) => p.placeOfBirth));

}
catch (e: any) {
    console.log(e.message);

}

//This is the output from my current code:
[ 'New York', 'New York', 'Orlando', 'Witchita' ]

下面是使用下面的console.log调用时的实际输出:

//Example 1
//call the function which groups the data together from 'placeOfBirth':

console.log(groupBy(input, (p: Person) => p.placeOfBirth));

//Output from console.log:

{
  New York: [
    { name: 'Andy', yearOfBirth: 1984, placeOfBirth: 'New York' },
    { name: 'John', yearOfBirth: 1995, placeOfBirth: 'New York' }
  ],
  Orlando: [ { name: 'Bill', yearOfBirth: 1995, placeOfBirth: 'Orlando' } ],
  Witchita: [ { name: 'Tim', yearOfBirth: 1989, placeOfBirth: 'Witchita' } ]
}

//Example 2
//call the function which groups the data together from 'yearOfBirth':

console.log(groupBy(input, (p: Person) => p.yearOfBirth));

//Output from console.log:

{
  '1984': [ { name: 'Andy', yearOfBirth: 1984, placeOfBirth: 'New York' } ],
  '1995': [
    { name: 'John', yearOfBirth: 1995, placeOfBirth: 'New York' },
    { name: 'Bill', yearOfBirth: 1995, placeOfBirth: 'Orlando' }
  ],
  '1989': [ { name: 'Tim', yearOfBirth: 1989, placeOfBirth: 'Witchita' } ]
}
dojqjjoe

dojqjjoe1#

您是否注重性能?
如果没有,您可以尝试以下操作:

function groupBy<I extends unknown>(
  input: I[],
  predicate: (i: I) => string | number
) {
  return input.reduce((curr, i) => {
    const key = predicate(i);

    return {
      ...curr,
      [key]: [...(curr[key] ?? []), i]
    };
  }, {});
}

这里有一个沙箱来尝试一下:https://codesandbox.io/s/unruffled-morse-nwjjsy?file=/src/index.ts

e37o9pze

e37o9pze2#

使用下面的函数,传递你的对象数组和键名进行分组,然后根据你发送的键获取分组数据:

const groupByKey = <T>(objectArray: T[], property: string) => {
      return objectArray.reduce(
          (acc: { [x: string]: any[]; }, obj: { [x: string]: any; }) => {
          const key = obj[property];
          if (!acc[key]) {
              acc[key] = [];
          }
          acc[key].push(obj);
          return acc;
      }, 
      {});
  }

//Usage:
  const groupedData = groupByKey(personsList, 'placeOfBirth');
nxowjjhe

nxowjjhe3#

我找到了一个解决方案,最终将数据分组在一起。我将分享下面的代码给其他寻找类似解决方案的人:

interface Person {
    name: string;
    yearOfBirth: number;
    placeOfBirth: string;
}

const input: Person[] = [
    {
        name: "Andy",
        yearOfBirth: 1984,
        placeOfBirth: "New York",
    },
    {
        name: "John",
        yearOfBirth: 1995,
        placeOfBirth: "New York",
    },
    {
        name: "Bill",
        yearOfBirth: 1995,
        placeOfBirth: "Orlando",
    },
    {
        name: "Tim",
        yearOfBirth: 1989,
        placeOfBirth: "Witchita",
    },
];

function groupBy(input: Person[], groupFunc: (item: Person) => any): { [key: string]: Person[] } {
    const groups: { [key: string]: Person[] } = {};

    input.forEach(item => {
        const groupKey = groupFunc(item);
        if (!groups[groupKey]) {
            groups[groupKey] = [];
        }
        groups[groupKey].push(item);
    });

    return groups;
}

try {
    console.log(groupBy(input, (p: Person) => p.yearOfBirth));

}
catch (e: any) {
    console.log(e.message);
}

export { }

相关问题