typescript 改进代码-删除数组中重复的情况

yyhrrdl8  于 2023-05-01  发布在  TypeScript
关注(0)|答案(2)|浏览(234)

我写了代码来删除数组中的重复项,但我觉得它可以做得更优雅。请提出建议。

接口定义
export interface SomeClass {
  version: number,
  typeDescription: string
}
测试数据
sthClass: SomeClass[] = [
  { typeDescription: "typeA", version: 10 },
  { typeDescription: "typeA", version: 21 },
  { typeDescription: "typeB", version: 101 },
  { typeDescription: "typeC", version: 199 },
  { typeDescription: "typeA", version: 220 },
  { typeDescription: "typeB", version: 33 },
  { typeDescription: "typeA", version: 15},
];
业务逻辑删除重复并保留版本号最大的一个
for (let index = this.sthClass.length - 1; index >= 0; index--) {
  filterArr = this.sthClass.filter(item => item.typeDescription == this.sthClass[index].typeDescription);

  if (filterArr.length > 1) {
    //sort in Desc Order
    filterArr.sort((a: SomeClass, b: SomeClass) => b.version - a.version);

    let idx = this.sthClass.findIndex(k => filterArr[1] === k)
    this.sthClass.splice(idx, 1);
  }
}
xtfmy6hx

xtfmy6hx1#

一种在线性时间内执行此操作的方法是使用reduce()和JS obejct(或者Map)来有效地查找是否已经遇到具有该值的typeDescription,以及当前项的版本是否更高。最后,您可以使用Object.values()获取值。

const sthClass = [
    { typeDescription: "typeA", version: 10 },
    { typeDescription: "typeA", version: 21 },
    { typeDescription: "typeB", version: 101 },
    { typeDescription: "typeC", version: 199 },
    { typeDescription: "typeA", version: 220 },
    { typeDescription: "typeB", version: 33 },
    { typeDescription: "typeA", version: 15 },
];

const output = Object.values(sthClass.reduce((acc, cur) => {
    if (!Object.hasOwn(acc, cur.typeDescription)) {
        acc[cur.typeDescription] = cur;
        return acc;
    }
    if (cur.version > acc[cur.typeDescription].version) {
        acc[cur.typeDescription] = cur
    }
    return acc;
}, {}));

console.log(output);
.as-console-wrapper {
    max-height: 100% !important;
    top: 0;
}

或者:

还可以创建一个工作的,但较慢(O(n log n)与上面的O(n)相比),而且在我看来也不那么优雅的使用排序的解决方案。
1.按typeDescription排序,然后按降序排序版本
1.通过跟踪前一个typeDescription只保留组的第一个元素

const sthClass = [
    { typeDescription: "typeA", version: 10 },
    { typeDescription: "typeA", version: 21 },
    { typeDescription: "typeB", version: 101 },
    { typeDescription: "typeC", version: 199 },
    { typeDescription: "typeA", version: 220 },
    { typeDescription: "typeB", version: 33 },
    { typeDescription: "typeA", version: 15 },
];

sthClass.sort((a, b) => a.typeDescription.localeCompare(b.typeDescription) || b.version - a.version);
let previous = undefined;
const output2 = sthClass.reduce((acc, cur) => {
    if (cur.typeDescription !== previous) {
        acc = [...acc, cur]
    }
    previous = cur.typeDescription;
    return acc;
}, []);
console.log(output2);
.as-console-wrapper {
    max-height: 100% !important;
    top: 0;
}

另一种变体只是由于排序而较慢,通常不能比O(n log n)更快,但如果由于您的数据,您知道您可以使用一些专门的算法在线性时间内排序,则此解决方案可能更快/更内存有效。

i7uq4tfw

i7uq4tfw2#

以下是我的解决方案:
1.初始化一个空对象obj。
1.循环遍历sthClass数组中的每个对象。
1.检查对象中是否存在当前对象的typeDescription属性。
1.如果存在,则将当前对象的version属性与obj中相同typeDescription的现有值进行比较。如果当前对象的版本较大,则用当前对象的版本更新obj中typeDescription的值。
1.如果它不存在,则将当前对象的typeDescription和版本添加到obj。
1.循环结束后,obj将包含唯一的typeDescription和每个typeDescription的最大版本。
代码的输出将是一个对象,其中包含唯一的typeDescription作为键,每个typeDescription的最大版本号作为值。

let sthClass = [
  { typeDescription: "typeA", version: 10 },
  { typeDescription: "typeA", version: 21 },
  { typeDescription: "typeB", version: 101 },
  { typeDescription: "typeC", version: 199 },
  { typeDescription: "typeA", version: 220 },
  { typeDescription: "typeB", version: 33 },
  { typeDescription: "typeA", version: 15},
];

let obj = {};

for(let i = 0; i<sthClass.length; i++){
  if(obj[sthClass[i].typeDescription]){
    obj[sthClass[i].typeDescription] = obj[sthClass[i].typeDescription] < sthClass[i].version ? sthClass[i].version : obj[sthClass[i].typeDescription];
  } else {
    obj[sthClass[i].typeDescription] = sthClass[i].version;
  }
}

console.log(obj);

相关问题