在打字稿中实现Set,特别是IterableIterator <[T,T]>

问题描述

我正在使用Typescript中的Set实现。我希望它采用set的接口,但有一些区别,我似乎对以下问题有疑问:entries()

我已经在对象上实现了next(),该对象返回以下任一值:

{
 value: elementAt(index),done: false;
}

{
value: undefined,done: true
}

但这不适用于

entries() : IterableIterator<[T,T]>

,我似乎找不到任何有关执行此操作的参考。有人可以帮忙吗?我的第一个想法是,价值的价值必须有所不同,但到目前为止,我尝试过的一切都没有奏效。

解决方法

来自the documentation of Set.prototype.entries()

entries() 方法返回一个新的Iterator对象,该对象包含{{{1} 1}}对象,按插入顺序。对于[value,value]对象,没有像Set对象中那样的键。但是,为了使API与Set对象相似,此处每个 entry key value 都具有相同的值,以便返回数组Map

这意味着要使对象满足Map接口,它需要为其[value,value]方法返回与它的Setentries()方法不同的迭代器。具体来说,您需要使迭代器结果的values()成对,因此keys()返回类似

的内容
value

希望有所帮助;祝你好运!

,

这是我在抽象类中实现(扩展)Set 接口的方法。就我而言,我希望用户定义他们自己的(扩展的)抽象方法实现。

我将大部分事情都委托给了 _values 集,因此我不必搞太多。

VS Code 完成了大部分工作(它可以帮助您找到实现方法)。我用 Google 搜索了一下,找到了 foreach 实现。

底部是如何使用方法实例化新类的示例。

/** Wrap a Set to support multiple values,e.g.,foos are objects in a set,but each foo has an "opposite" */
export abstract class SetWithOpposite<T> implements Set<T> {

    abstract setOpposite(value: T) : this
    abstract clearOpposite(value: T) : this

    add(value: T): this {
        if (!this._values.has(value)) {
            this._values.add(value)
            this.setOpposite(value)
        }
        return this
    }

    constructor(iterable?: T[]) {
        this.clear();

        if (iterable === undefined) {
            return;
        }

        if (!Array.isArray(iterable)) {
            throw new Error("Non-array iterables not supported.");
        }

        for (const value of iterable) {
            this.add(value);
        }
    }

    clear(): void {
        this._values.clear()
    }

    delete(value: T): boolean {
        if (this._values.has(value)) this.clearOpposite(value)
        return this._values.delete(value)
    }

    forEach(callbackfn: (value: T,value2: T,set: Set<T>) => void,thisArg?: any): void {
        for (const element of this._values.keys()) {
            callbackfn.call(thisArg,element,this);
        }
    }

    has(value: T): boolean {
        return this._values.has(value)
    }

    get size(): number {
        return this._values.size;
    }

    entries(): IterableIterator<[T,T]> {
        return this._values.entries()
    }

    keys(): IterableIterator<T> {
        return this._values.keys()
    }

    values(): IterableIterator<T> {
        return this._values.values()
    }

    [Symbol.iterator](): IterableIterator<T> {
        return this.values()
    }

    [Symbol.toStringTag]: string;

    _values = new Set<T>()

}

客户端定义和使用 SetWithOpposite 的具体实现:

import { SetWithOpposite } from "./setWithOpposite";

const incomingAccesses = new class extends SetWithOpposite<String> {
    setOpposite(value: String): this {
        console.log(`setOpposite: ${value}`)
        return this
    }
    clearOpposite(value: String): this {
        console.log(`clearOpposite: ${value}`)
        return this
    }
}

let entity = new String('Fred')

incomingAccesses.add(entity)

entity = new String('Nancy')

incomingAccesses.add(entity)

incomingAccesses.forEach(element => {
    console.log(`foreach element: ${element}`)
});

incomingAccesses.delete(entity)

for (const entry of incomingAccesses) {
    console.log(entry)
}