Arrays 如何确保数组中的所有元素都是唯一的?

Arrays 如何确保数组中的所有元素都是唯一的?,arrays,typescript,Arrays,Typescript,作为家庭作业项目的一部分,我正在用Typescript为学校构建Linq框架。谈到Select方法时,我遇到了一个问题。我将属性数组传递给Select,但问题是Typescript允许数组中存在重复值。在Typescript或Javascript中是否有一种方法可以使数组只包含唯一的值 现在,Select方法如下所示: 在界面中: Select: <K extends keyof T>(this: Table<T, U>, ...properties: K[]) =&g

作为家庭作业项目的一部分,我正在用Typescript为学校构建Linq框架。谈到
Select
方法时,我遇到了一个问题。我将属性数组传递给
Select
,但问题是Typescript允许数组中存在重复值。在Typescript或Javascript中是否有一种方法可以使数组只包含唯一的值

现在,
Select
方法如下所示:

在界面中:

 Select: <K extends keyof T>(this: Table<T, U>, ...properties: K[]) => Table<Omit<T, K>, Pick<T, K> & U>
Select:(this:Table,…properties:K[])=>Table
实施:

    Select: function <K extends keyof T>(this: Table<T, U>, ...properties: K[]): Table<Omit<T, K>, Pick<T, K> & U> {
        let selection = this.data.First.map(entry => pickMany(entry, properties))

        let result = this.data.map(
            first => first.map(entry => omitMany(entry, properties))
            ,
            second => merge_list_types(second.zip(selection))
        )

        return Table(result)
    }
Select:function(this:Table,…properties:K[]):Table{
让selection=this.data.First.map(条目=>pickMany(条目,属性))
让结果=this.data.map(
first=>first.map(条目=>ommitmany(条目,属性))
,
second=>合并列表类型(second.zip(选择))
)
返回表(结果)
}
现在可以说:

客户。选择(“姓名”、“姓名”、“年龄”)


正如预期的那样,上面的代码将给我一个类型错误,因为已经选择了
'name'

您不能以常规方式确保数组的唯一性(至少不能以受支持的常规方式,您可以使用递归类型别名执行一些疯狂的操作,但它们可能会从一个版本切换到另一个版本)

我们可以创建一个条件类型,以确保最多多个元素的唯一性,并根据需要添加更多元素

type Omit<T, K extends PropertyKey> = Pick<T, Extract<keyof T, K>>
type IsUnique<T extends any[]> = UK0<T, "Items are not unique", {}>

type Tail<T extends any[]> = ((...a: T) => void) extends (p: any, ...t: infer P) => void ? P : [];
type UK0<T extends any[], TErr, TOk> = T extends [] ? TOk : T[0] extends Tail<T>[number] ? TErr : UK1<Tail<T>, TErr, TOk>
type UK1<T extends any[], TErr, TOk> = T extends [] ? TOk : T[0] extends Tail<T>[number] ? TErr : UK2<Tail<T>, TErr, TOk>
type UK2<T extends any[], TErr, TOk> = T extends [] ? TOk : T[0] extends Tail<T>[number] ? TErr : UK3<Tail<T>, TErr, TOk>
type UK3<T extends any[], TErr, TOk> = T extends [] ? TOk : T[0] extends Tail<T>[number] ? TErr : UK4<Tail<T>, TErr, TOk>
type UK4<T extends any[], TErr, TOk> = T extends [] ? TOk : T[0] extends Tail<T>[number] ? TErr : UK5<Tail<T>, TErr, TOk>
type UK5<T extends any[], TErr, TOk> = T extends [] ? TOk : T[0] extends Tail<T>[number] ? TErr : UK6<Tail<T>, TErr, TOk>
type UK6<T extends any[], TErr, TOk> = T extends [] ? TOk : T[0] extends Tail<T>[number] ? TErr : "Array to big"

class Table<T, U> {
    Select = function <K extends Array<keyof T>>(this: Table<T, U>, ...properties: K & IsUnique<K>): Table<Omit<T, K[number]>, Pick<T, K[number]> & U> {

        return null!;
    }
}

new Table<{ a: 0, b: 0}, {}>().Select("a") //ok
new Table<{ a: 0, b: 0}, {}>().Select("a", "a") // err
new Table<{ a: 0, b: 0}, {}>().Select("a", "b") //ok
类型省略=拾取
类型IsUnique=UK0
类型Tail=(…a:T)=>void)扩展(p:any,…T:inferp)=>void?P:[];
类型UK0=T扩展[]?TOk:T[0]延伸尾部[编号]?地球:UK1
类型UK1=T扩展[]?TOk:T[0]延伸尾部[编号]?地球:UK2
类型UK2=T扩展[]?TOk:T[0]延伸尾部[编号]?地球:UK3
类型UK3=T扩展[]?TOk:T[0]延伸尾部[编号]?地球:UK4
类型UK4=T扩展[]?TOk:T[0]延伸尾部[编号]?地球:UK5
类型UK5=T扩展[]?TOk:T[0]延伸尾部[编号]?地球:UK6
类型UK6=T扩展[]?TOk:T[0]延伸尾部[编号]?地球:“阵列变大”
类表{
选择=函数(此:表,…属性:K&IsUnique):表{
返回null!;
}
}
新建表格()。选择(“a”)//确定
新建表格()。选择(“a”,“a”)//错误
新建表格()。选择(“a”、“b”)//确定
更好的方法实际上是使用对象类型,对象本质上不允许密钥复制

class Table<T, U> {
    Select = function <K extends Partial<Record<keyof T, true>>>(this: Table<T, U>, properties: K): Table<Omit<T, keyof K>, Pick<T, keyof K> & U> {

        return null!;
    }
}

new Table<{ a: 0, b: 0}, {}>().Select({ a: true }) //ok
new Table<{ a: 0, b: 0}, {}>().Select({ a: true, a: true }) // err
new Table<{ a: 0, b: 0}, {}>().Select({ a: true, b: true }) //ok
类表{
选择=函数(此:表格,属性:K):表格{
返回null!;
}
}
新建表()。选择({a:true})//确定
新建表()。选择({a:true,a:true})//错误
新建表()。选择({a:true,b:true})//确定

使用不允许重复的集合类型Java和Javascript是两码事。请更正您的标签。我说的是Java吗?抱歉,我的意思是Javascript谢谢你的更正我正在考虑只传递一个对象作为参数,但我想老师们会更喜欢这种语法
Select(“a”,“b”)
@I作为一名老师,我可以告诉你,这是一个很好的问题。一般来说,我们不介意人们问问题:-)我想回到你们这里,在这个例子中,我的一位老师在halway提出了另一个解决方案。通过使用
排除
。我不知道如何实现这一点,但它与生成K类型元素的数组类型以及排除allready选择的值有关。“你知道他是什么意思吗?或者如何实现它。@我想最好的办法是,递归类型别名问题是无法回避的。”。不允许使用递归类型别名(非常有限的情况除外)。您可以某种程度上欺骗编译器让您这样做,但这是a)不推荐b)随着递归性检查的改进,在未来的版本中很可能会出现中断(而且它们确实存在,因为GH中充满了递归类型别名,它们可以工作,但不再工作)。如果你的老师有一个更好的版本,我很想看看,但我怀疑它对任意大的阵列有效。我会让你知道的