09898-medium-zhao-chu-mu-biao-shu-zu-zhong-zhi-chu-xian-guo-yi-ci-de-yuan-su

Back

// 你的答案
type IncludesItem<T, U> = U extends U ? [U] extends [T] ? true : false : false
type FindEles<T extends any[], U extends any[] = []> = T extends [infer A, ...infer R] ? 
  IncludesItem<A, U[number] | R[number]> extends false ? [A, ...FindEles<R, U>] : FindEles<R, [...U, A]>
  : T

Solution by heyuelan #34727

type FindEles<T extends unknown[], U = never> = T extends [infer F, ...infer R]
  ? F extends U | R[number]
    ? FindEles<R, U | F>
    : [F, ...FindEles<R, U | F>]
  : [];

Solution by yukicountry #34352

type FindEles<T extends any[], A extends any[] = []> = T extends [infer F, ...infer R]
  ? F extends A[number]
    ? FindEles<R, A>
    : F extends R[number] // Expect<Equal<FindEles<[1, 2, number]>, [1, 2, number]>> not pass
      ? FindEles<R, [...A, F]>
      : [F, ...FindEles<R, [...A, F]>]
  : []

In order for Expect<Equal<FindEles<[1, 2, number]>, [1, 2, number]>> to pass, replace F extends R[number] with R extends [...infer _, F]/R extends [F, ...infer _].

type FindEles<T extends any[], A extends any[] = []> = T extends [infer F, ...infer R]
  ? F extends A[number]
    ? FindEles<R, A>
    : R extends [...infer _, F]
      ? FindEles<R, [...A, F]>
      : R extends [F, ...infer _]
        ? FindEles<R, [...A, F]>
        : [F, ...FindEles<R, [...A, F]>]
  : []

Solution by MAXLZ1 #34310

type FindEles<T extends any[], Finded extends any[] = [], Res extends any[] = []> = T extends [infer R, ...infer rest] ?
R extends [...Finded, ...rest][number] ? FindEles<rest, [...Finded, R], Res> : FindEles<rest, Finded, [...Res, R]> : Res

Solution by ouzexi #34114

type isEqual<F, S> = (<G>() => G extends F ? 1 : 2) extends (<G>() => G extends S ? 1 : 2) ? true : false

type Remove<T extends any[], S, Result extends any[] = []> = T extends [infer First, ...infer Rest] 
  ? isEqual<First, S> extends true
    ? [...Result, ...Rest]
    : Remove<Rest, S, [...Result, First]>
  : Result 

type FindEles<T extends any[], All extends any = never, Unique extends any[] = []> = T extends [infer First, ...infer Rest] 
  ? First extends All
    ? FindEles<Rest, All, Remove<Unique, First>>
    : FindEles<Rest, All | First, [...Unique, First]>
  : Unique

Solution by PiligrimStas #33804

type FindEles<
  T extends any[],
  Arr extends any[] = [],
  Ret extends any[] = []
> = T extends [infer Ele, ...infer Rest]
  ? Ele extends [...Rest, ...Arr][number]
    ? FindEles<Rest, [...Arr, Ele], Ret>
    : FindEles<Rest, [...Arr], [...Ret, Ele]>
  : Ret;

Solution by sunupupup #33447

type FindEles<T extends number[], ValKeys = {[K in keyof T & `${number}` as T[K]]: K}, R extends number[] = []>
  = T extends [...infer Lead extends number[], infer Last extends keyof ValKeys & number]
    ? FindEles<Lead, ValKeys, ValKeys[Last] extends `${Lead['length']}` ? [Last, ...R] : R>
  : R

Playground

Solution by teamchong #33352

// your answers
type FindEles<T extends any[]> = T extends [infer S, ...infer L]
? L extends S
  ? FindEles<L> : [S]
    :[]

Solution by pea-sys #33351

type FindEles<T extends any[], VisitedItems extends unknown[] = [], UniqItems extends unknown[] = []> = T extends [infer First, ...infer Rest]
  ? First extends (VisitedItems[number] | Rest[number])
    ? FindEles<Rest, [...VisitedItems, First], UniqItems>
    : FindEles<Rest, [...VisitedItems, First], [...UniqItems, First]>
  : UniqItems

Solution by keyurparalkar #32726

type Filter<T extends any[], P, R extends any[] = []> = T["length"] extends 0
  ? R
  : T[0] extends P
  ? Filter<T extends [any, ...infer U] ? U : never, P, [...R, T[0]]>
  : Filter<T extends [any, ...infer U] ? U : never, P, R>;

type FindEles<T extends number[], R extends number[] = T, Once extends number = never, More extends number = never> = 
  R["length"] extends 0
    ? Filter<T, Once>
    : R extends [infer F extends number, ...infer U extends number[]]
      ? F extends More
        ? FindEles<T, U, Once, More>
        : F extends Once
          ? FindEles<T, U, Exclude<Once,F>, More | F>
          : FindEles<T, U, Once | F, More>
      : never;

Solution by vangie #32196

type FindEles<T extends readonly any[], Uniques extends readonly any[] = [], Seen extends readonly any[] = []> =
  T extends [infer F, ...infer Tail] // does the list contains any element?
    ? F extends Seen[number] // the first element of the list is already seen?
      ? FindEles<Tail, Uniques, Seen>
      : F extends Tail[number] // is the first element contained in the rest of the list?
        ? FindEles<Tail, Uniques, [...Seen, F]>
        : FindEles<Tail, [...Uniques, F], [...Seen, F]>
    : Uniques

I tried to make the generic types very self explicables

Solution by joyanedel #32157

Readable solution

type FindEles<T extends unknown[]> = FindElesInternal<T>;
type FindElesInternal<
    Cur extends unknown[], 
    Prev extends unknown[] = [], 
    Acc extends unknown[] = []
> = 
    Cur extends [infer Head, ...infer Tail] 
        ? Head extends [...Prev, ...Tail][number] 
            ? FindElesInternal<Tail, [...Prev, Head], Acc>
            : FindElesInternal<Tail, [...Prev, Head], [...Acc, Head]>
        : Acc
;

Solution by sdrjs #31844

// 你的答案

type FindEles<T extends any[], P extends any[] = []> = 
  T extends [infer S, ...infer O] ? (S extends P[number] ? FindEles<O, [...P, S]> : (S extends O[number] ? FindEles<O, [...P, S]> : [S, ...FindEles<O, [...P, S]>])) : [];

Solution by tarotlwei #31746

type FindOnceElement<
  T extends any[],
  P extends any[] = [],
  K extends any[] = []
> = T extends [infer F, ...infer R]
  ? FindOnceElement<
      R,
      [...P, F],
      F extends [...P, ...R][number] ? K : [...K, F]
    >
  : K;

Solution by moonpoet #31027

type FindEles<T extends unknown[], R extends unknown[] = [], U extends unknown[] = []> = T extends [
  infer F,
  ...infer Rest,
]
  ? F extends Rest[number] | U[number]
    ? FindEles<Rest, [...R], [...U, F]>
    : FindEles<Rest, [...R, F], [...U]>
  : R;

Solution by leejaehyup #30865

type FindEles<T extends any[], U extends any[] = [], O extends any[] = []> = T extends [infer A, ...infer B] ? A extends O[number] ? FindEles<B, U, [...O, A]> : A extends B[number] ? FindEles<B, U, [...O, A]> : FindEles<B, [...U, A], [...O, A]> : U

Solution by dreamluo-plus #30685

// 1.声明一个MyIncludes, 用来判断当前元素是否出现在其他元素中(MyIncludes可以根据场景来考虑是否要Equal)
// 2.Iterated用来收集遍历过的元素, List用来收集没出现过的原
// 3.解构第一个元素, 用他和其他的元素作对比,  其他元素就是Iterated + Other
// 4.如果没出现, 就放到List, 然后继续递归

type MyIncludes<T extends any[], K> = T extends [infer First, ...infer Other] ? First extends K ? true : MyIncludes<Other, K> : false

type FindEles<T extends any[], Iterated extends any[] = [], List extends any[] = []> = T extends [infer First, ...infer Other]
  ? MyIncludes<[...Iterated, ...Other], First> extends true
    ? FindEles<Other, [...Iterated, First], List>
    : FindEles<Other, [...Iterated, First], [...List, First]>
  : List

Solution by xiahouwei #30586

type ToString<T extends unknown[], Result extends string = ''> = T extends [
  infer R extends number,
  ...infer Rest,
]
  ? ToString<Rest, `${Result}${R}`>
  : Result

type FindEles<T extends unknown[], S = ToString<T>, Result extends unknown[] = []> = T extends [
  infer R extends number,
  ...infer Rest,
]
  ? FindEles<Rest, S, S extends `${string}${R}${string}${R}${string}` ? Result : [...Result, R]>
  : Result

先把数组转成字符串,再推断就简单了

Solution by zhangyu1818 #30274

Duplicates用于存储重复出现的元素,当F即不在T中也不再Duplicates中,则表示它只出现了一次

type FindEles<T extends any[], Duplicates extends any[] =[]> = 
  T extends [infer F, ...infer R] 
    ? F extends R[number] 
      ? FindEles<R, [...Duplicates, F]> :  F extends Duplicates[number] 
      ? FindEles<R, Duplicates> : [F, ...FindEles<R, Duplicates>]
    :[]

Solution by sv-98-maxin #30127

type FindEles<
  T extends any[],
  P extends any[] = [],
  R extends any[] = []
> = T extends [infer First, ...infer Rest]
  ? First extends [...P, ...Rest][number]
    ? FindEles<Rest, [...P, First], R>
    : FindEles<Rest, P, [...R, First]>
  : R;

Solution by idebbarh #29958

type FindEles<T extends unknown[], U = never> =
    T extends [infer F, ...infer R]
        ? F extends U | R[number]
            ? FindEles<R, U | F>
            : [F, ...FindEles<R, U>]
        : [];

Solution by funnyhaha17 #29795

type FindEles<T extends any[], Prevs extends any[] = []> = T extends [
  infer Item,
  ...infer Rest
]
  ? Item extends Prevs[number] | Rest[number]
    ? FindEles<Rest, [...Prevs, Item]>
    : [Item, ...FindEles<Rest, [...Prevs, Item]>]
  : [];

Solution by DoubleWoodLin #28853

type In<T extends any[], U> = U extends T[number] ? true : false;

type Filter<T extends any[], U extends any, S extends any[] = []> = T extends [infer L, ...infer Rest]
  ? Filter<Rest, U, L extends U
    ? S
    : [...S, L]>
  : S

type FindEles<T extends any[], S extends any[] = []> = T extends [infer First, ...infer Rest]
  ? FindEles<Filter<T, First>, In<Rest, First> extends true
    ? S
    : [...S, First]>
  : S;

Solution by JohnhanLiu #28832

type ValueInArr<T extends any[], Val extends any> = T extends [infer First, ...infer Rest] ? First extends Val ? true : ValueInArr<Rest, Val> : false
type FindEles<T extends any[], Trash extends any[] = [], Acc extends any[] = []> = T extends [infer First, ...infer Rest] ? ValueInArr<[...Rest, ...Trash], First> extends true ? FindEles<Rest, [...Trash, First], Acc> : FindEles<Rest, Trash, [...Acc, First]> : Acc

Solution by julianmendonca #28813

type IsRepeat<T extends unknown[], I> = T extends [infer First, ...infer Rest]
  ? Equal<I, First> extends true
    ? true
    : IsRepeat<Rest, I>
  : false;

type FindEles<T extends unknown[], List extends unknown[] = [], Result extends unknown[] = []> = List['length'] extends T['length']
  ? Result
  : T extends [infer First, ...infer Rest]
    ? IsRepeat<Rest, First> extends true
      ? FindEles<[...Rest, First], [...List, First], Result>
      : FindEles<[...Rest, First], [...List, First], [...Result, First]>
  : never;

Solution by NameWjp #28751

// 你的答案

type FindEles<
  T extends any[],
  K extends any[] = [],
  U extends any[] = [],
  O extends { [index: string]: any } = {},
> = T extends [infer A extends number | string, ...infer B]
  ? A extends B[number]
    ?
    FindEles<
      B,
      [...K, 1],
      U,
      { [P in keyof O | A]: P }
    >
    : unknown extends O[A] ?
      FindEles<
      B,
      [...K, 1],
      [...U, A],
      O>
      :
      FindEles<
      B,
      [...K, 1],
      U,
      O
      >
  : U

Solution by xpbsm #28586

type FindEles<
  Items extends unknown[],
  ProcessedItems extends unknown[] = [],
  UniqueItems extends unknown[] = []
> = Items extends [infer Head, ...infer Tail]
  ? FindEles<
      Tail,
      [...ProcessedItems, Head],
      Head extends [...ProcessedItems, ...Tail][number]
        ? UniqueItems
        : [...UniqueItems, Head]
    >
  : UniqueItems;

Solution by yevhenpavliuk #28416

type Include<T, U> = T extends [infer F, ...infer R]
  ? Equal<F, U> extends true
    ? true
    : Include<R, U>
  : false;

type FindEles<
  T extends unknown[],
  A extends unknown[] = [],
  P extends unknown[] = []
> = T extends [infer F, ...infer R]
  ? Include<[...P, ...R], F> extends true
    ? FindEles<R, A, [...P, F]>
    : FindEles<R, [...A, F], [...P, F]>
  : A;

Solution by DoGukKim #28273

引入两个泛型,一个用来保存结果,一个用来存储计算过的数字,这样做的目的是,通过 [...Rest, ...O] 我们得到的数组是不包含 F 本身的,不然返回永远都是 true

这样我们通过 [number] 将数组转成联合类型,再递归判断即可

playground

type FindEles<T extends any[], U extends any[] = [], O extends any[] = []> = T extends [infer F, ...infer Rest]
  ? F extends [...Rest, ...O][number]
    ? FindEles<Rest, U, [...O, F]>
    : FindEles<Rest, [...U, F], [...O, F]>
  : U

Solution by linjunc #28152

type ExcludeArrItem<T extends any[], U> = T extends [infer N, ...infer Rest] ? N extends U ? [...ExcludeArrItem<Rest, U>] : [N, ...ExcludeArrItem<Rest, U>] : []

type AppearOnlyOnce<T extends any[]> = T extends [infer N, ...infer Rest] ? 
    ExcludeArrItem<Rest, N>['length'] extends Rest['length'] ? 
        [N, ...AppearOnlyOnce<Rest>] :
        [...AppearOnlyOnce<ExcludeArrItem<Rest, N>>]
    : []

Solution by HenrryShaw #27780