09989-medium-tong-ji-shu-zu-zhong-de-yuan-su-ge-shu

Back

type CountElementNumberToObject<T extends any[], U extends Record<PropertyKey, any[]> = {}> = T extends [infer First, ...infer Rest]
  ? [First] extends [never]
    ? CountElementNumberToObject<Rest, U>
    : First extends any[]
      ? CountElementNumberToObject<[...First, ...Rest], U>
      : CountElementNumberToObject<Rest, {
        [P in keyof U | First & PropertyKey]: P extends keyof U ? P extends First ? [...U[P], any] : U[P] : [any]
      }>
  : {
    [P in keyof U]: U[P]['length']
  }

Solution by 2083335157 #34944

// 你的答案
type CountElementToObjectArr<T, Res extends Record<PropertyKey, any[]> = {}> = T extends [infer A, ...infer R] ? 
  [A] extends [never] ? CountElementToObjectArr<R, Res> : 
  A extends any[] ? CountElementToObjectArr<[...A, ...R], Res> :
  A extends PropertyKey ? 
    CountElementToObjectArr<R, {
      [P in A]: Res[P] extends any[] ? [...Res[P], never] : [never]
    } & {
      [P in keyof Res as P extends A ? never : P]: Res[P]
    }> : Res
  : Res

type CountElementNumberToObject<T> = CountElementToObjectArr<T> extends infer A ? 
  {
    [P in keyof A]: A[P] extends any[] ? A[P]['length'] : never
  } 
  : never

Solution by heyuelan #34728

type CountElementNumberToObject<T, Result extends {[key:keyof any]: any[]} = {}> = 
    T extends [infer F, ...infer R] ?
        F extends any[] ? CountElementNumberToObject<[...F, ...R], Result> : 
            F extends keyof Result ? CountElementNumberToObject<R, {
                [K in keyof Result]: F extends K ? [...Result[K], unknown]: Result[K]
            }>: CountElementNumberToObject<R, {
                [K in (keyof Result | F&PropertyKey)]: K extends keyof Result ? Result[K]: [unknown]
            }>
        :{
            [K in keyof Result]: Result[K]["length"]
        }

思路: 类型计算中很难做1+1=2,通常是通过数据长度来做加法,那么这里计算中途,就用unkown[]的长度来表示被计数的值的出现次数

  1. T 不是空数组 & T[0]为数组,展开T[0]继续计算 ---> 递归CountElementNumberToObject<[...F, ...R], Result>
  2. T 不是空数组 & T[0]曾经被计数,增加计数字典中T[0]对应的value值的数组长度 ---> [...Result[K], unknown]
  3. T 不是空数组 & T[0]没有被计数, 计数字典中T[0]对应的value值为[unkown],长度为1,表示出现过一次
  4. T 为空数据,通过Result来计算真正结果,Result中value值修改为数组的长度

Solution by ndfhsledk #34520

type CountElementNumberToObject<T extends any[], U extends Record<any, any[]> = {}> = T extends [infer F, ...infer R]
  ? [F] extends [never]
    ? CountElementNumberToObject<R, U>
    : F extends any[]
      ? CountElementNumberToObject<[...F, ...R], U>
      : CountElementNumberToObject<R, {
        [K in (F & PropertyKey) | keyof U]: F extends keyof U
          ? K extends F
            ? [...U[K], any]
            : U[K]
          : [any]
      }>
  : { [K in keyof U]: U[K]['length'] }

Solution by MAXLZ1 #34312

type Flat<T extends any[]> = T extends [infer R, ...infer rest] ? R extends any[] ? [...Flat<R>, ...Flat<rest>] : [R, ...Flat<rest>] : T

type Count<T extends any[], V, U extends any[] = []> = T extends [infer R, ...infer rest] ? R extends V ? Count<rest, V, [...U, V]> : Count<rest, V, U> : U['length']

type CountElementNumberToObject<T extends any[], U extends any[] = Flat<T>> = {
  [K in U[number]]: Count<U, K>
}

Solution by ouzexi #34118

// 你的答案
type Put<T extends Record<PropertyKey, any[]>, K extends PropertyKey> = {
  [P in keyof T as P extends K ? never : P]: T[P]
} & {
  [P in K]: T[P] extends any[] ? [...T[P], null] : [null]
}

type CountElementNumberToObject<T extends any[], Res extends Record<PropertyKey, any[]> = {}> = 
  T extends [infer A, ...infer R] ? 
    [A] extends [never] ? CountElementNumberToObject<R, Res> :
    A extends any[] ? CountElementNumberToObject<[...A, ...R], Res> : 
    A extends PropertyKey ? CountElementNumberToObject<R, Put<Res, A>> : CountElementNumberToObject<R, Res>
  : {
    [P in keyof Res]: Res[P]['length']
  }

Solution by heyuelan #33869

type Flatten<T extends any[]> = T extends [infer First, ...infer Rest]
  ? First extends any[]
    ? [...Flatten<First>, ...Flatten<Rest>]
    : [First, ...Flatten<Rest>]
  : [];

type Help<
  T extends any[],
  Obj extends { [k: PropertyKey]: any[] } = { [P in T[number]]: [] }
> = T extends [
  infer First extends PropertyKey,
  ...infer Rest extends PropertyKey[]
]
  ? Help<
      Rest,
      {
        [K in keyof Obj]: K extends First ? [...Obj[K], 1] : Obj[K];
      }
    >
  : Obj;

type CountElementNumberToObject<Arr extends any[]> = {
  [K in keyof Help<Flatten<Arr>>]: Help<Flatten<Arr>>[K]["length"];
};

Solution by sunupupup #33448

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

type Count<T extends any[], X> = T extends [infer F, ...infer R]   
    ? F extends X 
      ? [F, ...Count<R, X>]
      : [...Count<R, X>]
  : []
  
type Mapped<T extends any[]> = {
  [key in T[number]] : Count<T, key>['length']
}

type CountElementNumberToObject<T extends any[]> = Mapped<Flatten<T>>

Solution by rimo030 #32738

type Flatten<T extends {}> = {
  [P in keyof T]: T[P];
};

type ExtendObjectWithNewKey<T extends {}, Key extends unknown> = Flatten<
  T & {
    // Sets the default value of new key to be 1
    [P in (number | string) & Key]: [1]['length']
  }
>;

type IncrementTheCountOfExistingKey<T extends {}, Key extends unknown> = {
  // For the existing key we increment the count
  [P in keyof T]: P extends Key ? [T[P], 1]['length'] : T[P]
};

type CountElementNumberToObject<
  T extends unknown[] = [],
  Acc extends {} = {},
> = T extends [infer F, ...infer R]
  ? F extends unknown[]
    ? CountElementNumberToObject<F, IncrementTheCountOfExistingKey<Acc, F>>
    : F extends keyof Acc
        ? // We update its freq
          CountElementNumberToObject<R, IncrementTheCountOfExistingKey<Acc, F>>
        : // We add F with freq = 1
          CountElementNumberToObject<R, ExtendObjectWithNewKey<Acc, F>>
  : Acc;

Solution by keyurparalkar #32685

type CountElementNumberToObject<
  T extends any[],
  U extends Record<any, any[]> = {}
> = T extends [never]
  ? {}
  : T extends [infer F, ...infer R]
  ? F extends any[]
    ? CountElementNumberToObject<[...F, ...R], U>
    : CountElementNumberToObject<
        R,
        {
          [K in keyof U | (F & PropertyKey)]: K extends keyof U
            ? K extends F
              ? [...U[K], any]
              : U[K]
            : [any];
        }
      >
  : { [K in keyof U]: U[K]["length"] };

Solution by vangie #32203

/* Reult */
type CountElementNumberToObject<T extends unknown[]> = ArrayValueToNumberValue<
  CountElement<
    FlatArray<T>
  >
>

/********** Helpers **********/

type FlatArray<T extends unknown[], R extends unknown[] = []> =
  T extends [infer A, ...infer Rest]
    ? [A] extends [never]
      ? FlatArray<Rest, R>
      : A extends unknown[]
        ? FlatArray<[...A, ...Rest], R>
        : FlatArray<Rest, [...R, A]>
    : R

type CountElement<
  T extends unknown[],
  Obj extends Record<string | number, number[]> = {},
> =
  T extends [infer A extends string | number, ...infer Rest]
    ? CountElement<Rest, Omit<Obj, A> & {
      [Key in A]: AddOne<Obj[A]>
    }>
    : Obj

type AddOne<T> = T extends number[] ? [...T, 0] : [0]

type ArrayValueToNumberValue<T extends Record<string | number, number[]>> = {
  [Key in keyof T]: T[Key]['length']
}

Solution by drylint #32045

type CountElementNumberToObject<T extends unknown[]> = CENTOInternal<FlattenWithoutNever<T>>;

type FlattenWithoutNever<T extends unknown[]> = 
    T extends [infer Head, ...infer Tail] 
        ? [Head] extends [never] 
            ? [...FlattenWithoutNever<Tail>]
            : Head extends unknown[]
                ? [...FlattenWithoutNever<Head>, ...FlattenWithoutNever<Tail>]
                : [Head, ...FlattenWithoutNever<Tail>]
        : []
;

type CENTOInternal<T extends unknown[], Acc extends Record<PropertyKey, any> = {}> = 
    T extends [infer Head extends PropertyKey, ...infer Tail] 
        ? Acc[Head] extends number 
            ? CENTOInternal<Tail, PlusOne<Acc, Head>>
            : CENTOInternal<Tail, AddProperty<Acc, Head>> 
        : Acc
;

type PlusOne<T, Property> = {
    [P in keyof T]: P extends Property ? PlusOneInternal<T[P]> : T[P];
}

type PlusOneInternal<T, Acc extends 1[] = []> = 
    T extends Acc["length"] 
        ? [...Acc, 1]["length"] 
        : PlusOneInternal<T, [...Acc, 1]>
;

type AddProperty<L, R extends PropertyKey> = {
    [P in keyof L | R]: 
        P extends keyof L 
            ? L[P] 
            : 1;
}

Solution by sdrjs #31876

// 你的答案

type MyRqual<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
type ExpandArray<T extends any[] | string | number> = 
  T extends [infer S, ...infer O] ? 
    S extends any[] ? [...ExpandArray<S>, ...ExpandArray<O>] : [S, ...ExpandArray<O>]
  : [];
type ItemInArrayCount<A extends any[], I, C extends any[] = []> = A extends [infer S, ...infer O] ? (MyRqual<I, S> extends true ? ItemInArrayCount<O, I, [1, ...C]> : ItemInArrayCount<O, I, [...C]> ) : C['length'];
type CountElementNumberToObject<T extends any[], U extends any[] = ExpandArray<T>> = {
  [P in U[number]]: ItemInArrayCount<U, P>;
}

Solution by tarotlwei #31747

type Flatten<T,R extends any[] = []> = 
  T extends [infer F,...infer L]?
    [F] extends [never]?
      Flatten<L,R>:
      F extends any[]?
        Flatten<L,[...R,...Flatten<F>]  >
        :Flatten<L,[...R,F]>
    :R 


type Count<
  T,
  R extends Record<string | number,any[]> = {}
> = 
T extends [infer F extends string | number,...infer L]?
  F extends keyof R?
    Count<L, Omit<R,F>& Record<F,[...R[F],0] > >
    : Count<L, R & Record<F,[0]>>
  :{
    [K in keyof R]:R[K]['length']
  }


type CountElementNumberToObject<
  T
> = 
  Count<Flatten<T>>

Solution by MyeonghoonNam #31324

type Flatten<T,R extends any[] = []> = 
  T extends [infer F,...infer L]?
    [F] extends [never]?
      Flatten<L,R>:
      F extends any[]?
        Flatten<L,[...R,...Flatten<F>]  >
        :Flatten<L,[...R,F]>
    :R 


type Count<
  T,
  R extends Record<string | number,any[]> = {}
> = 
T extends [infer F extends string | number,...infer L]?
  F extends keyof R?
    Count<L, Omit<R,F>& Record<F,[...R[F],0] > >
    : Count<L, R & Record<F,[0]>>
  :{
    [K in keyof R]:R[K]['length']
  }

Solution by gearonixx #31166

type Flatten<T, R extends any[] = []> = T extends [infer F, ...infer L]
  ? [F] extends [never]
    ? Flatten<L, R>
    : F extends any[]
    ? Flatten<L, [...R, ...Flatten<F>]>
    : Flatten<L, [...R, F]>
  : R;

type CountElementNumberToObject<
  T extends unknown[],
  U extends any[] = Flatten<T>,
  R extends Record<any, unknown[]> = { [K in U[number]]: [] },
> = U extends [infer F, ...infer Rest]
  ? CountElementNumberToObject<T, Rest, { [K in keyof R]: K extends F ? [...R[K], unknown] : R[K] }>
  : {
      [K in keyof R]: R[K]['length'];
    };

Solution by leejaehyup #30866

type Flat<T> = T extends [infer A, ...infer B] ? A extends any[] ? [...Flat<A>, ...Flat<B>] : [A, ...Flat<B>] : T
type Count<T, O, U extends any[] = []> = T extends [infer A, ...infer B] ? A extends O ? Count<B, O, [...U, O]> : Count<B, O, [...U]> : U['length']
type CountElementNumberToObject<T extends any[], U extends any[] = Flat<T>> = {
  [K in U[number]] : Count<U, K>
}

Solution by dreamluo-plus #30686

// your answers
type CountElementNumberToObject<T extends any[], U extends {any?:any[]} ={}> = 
  T extends [infer F, ...infer R]?
    [F] extends [never]? CountElementNumberToObject<R, U>:
    F extends any[]? CountElementNumberToObject<F, U>:
    F extends keyof U? 
      CountElementNumberToObject<R, {[K in keyof U]: U[K] extends any[]? K extends F? [...U[K], 1]: U[K]:never}> 
      : CountElementNumberToObject<R, {[K in keyof U | (F extends PropertyKey? F: never)]: K extends keyof U? U[K]: [1]}> 
  : {
    [K in keyof U]: U[K] extends any[]?  U[K]['length']: never
  }

Solution by yangyyou #30486

type Merge<A extends Record<keyof any, any[]>, B extends Record<keyof any, any[]>> = {
  [K in keyof A | keyof B]:
    K extends keyof A
      ? K extends keyof B
        ? [...A[K], ...B[K]]
        : A[K]
      : B[K]
}


type CountElement<T, M extends Record<keyof any, unknown[]> = {}> = T extends [infer F, ...infer Rest]
  ? [F] extends [never]
    ? CountElement<Rest, M>
    : F extends any[]
      ? CountElement<Rest, CountElement<F> extends Record<keyof any, any[]> ? Merge<M, CountElement<F>> : M>
      : CountElement<Rest, Merge<M, { [K in F & keyof any]: [unknown] }>>
  : M

type Count<T extends Record<keyof any, any[]>> = {
  [K in keyof T]: T[K]['length']
}

type CountElementNumberToObject<T> = Count<CountElement<T>>

Solution by XkSuperCool #30347

// 你的答案
type CountElementNumberToObject<T extends any[], U extends { any?: any[] } = {}> =
  T extends [infer F, ...infer R] ?
  [F] extends [never] ? CountElementNumberToObject<R, U> :
  F extends any[] ?
  CountElementNumberToObject<F, U> :
  CountElementNumberToObject<R,
    {
      [P in keyof U | (F extends PropertyKey ? F : never)]: P extends keyof U ? P extends F ? U[P] extends any[] ? [...U[P], ''] : U[P] : U[P] : ['']
    }>
  : {
    [P in keyof U]: U[P] extends any[] ? U[P]['length'] : never
  }

Solution by YE840926098 #30140

type PlusOne<
  N extends number,
  Acc extends number[] = []
> = Acc["length"] extends N ? [...Acc, 0]["length"] : PlusOne<N, [...Acc, 0]>;

type CountElementNumberToObject<
  T extends any[],
  R extends { [key: number]: number } = {}
> = T extends [never]
  ? R
  : T extends [infer First, ...infer Rest]
  ? First extends any[]
    ? CountElementNumberToObject<[...First, ...Rest], R>
    : CountElementNumberToObject<
        Rest,
        {
          [Key in keyof R | First]: Key extends keyof R
            ? Key extends First
              ? PlusOne<R[Key]>
              : R[Key]
            : 1;
        }
      >
  : R;

Solution by idebbarh #29959

/**转化为
 * {
 *  1: [1, 1]
 *  2: [1, 1]
 *  3: [1, 1]
 *  4: [1]
 *  5: [1]
 * }
 */
type CountElementNumberCounter<T extends any[], _Counter extends { [x: PropertyKey]: 1[] } = {}> =
  T extends [infer F extends PropertyKey | any[], ...infer R] ?
  (
    CountElementNumberCounter<R, F extends any[] ?
      CountElementNumberCounter<F, _Counter> :
      F extends PropertyKey ?
      { [P in keyof _Counter | F]: P extends keyof _Counter ? F extends P ? [..._Counter[P], 1] : _Counter[P] : [1] }/*pop*/ : never>
  ) : _Counter/*return*/;

type CountElementNumberToObject<T extends any[], U extends { [x: PropertyKey]: 1[] } = CountElementNumberCounter<T>> = [U] extends [never] ? {} : { [P in keyof U]: U[P][`length`] };

Solution by E-uler #29009

type Flat<T extends unknown[]> = T extends [infer Item, ...infer Rest]
  ? [Item] extends [never]
    ? Flat<Rest>
    : Item extends unknown[]
    ? [...Flat<Item>, ...Flat<Rest>]
    : [Item, ...Flat<Rest>]
  : [];

type CountElementNumberToObject<
  T extends unknown[],
  F extends unknown[] = Flat<T>,
  Res extends Record<keyof any, readonly unknown[]> = {}
> = F extends [infer Item, ...infer Rest]
  ? Item extends keyof any
    ? CountElementNumberToObject<
        T,
        Rest,
        Omit<Res, Item> & {
          [K in Item]: K extends keyof Res ? [...Res[K], unknown] : [unknown];
        }
      >
    : CountElementNumberToObject<T, Rest, Res>
  : { [K in keyof Res]: Res[K]["length"] };

Solution by DoubleWoodLin #28860


type Value = number | string | never;
type Item = Value | Item[];

type GetMap<
  V extends Value,
  Map extends Record<Value, 0[]> = {}
> = V extends keyof Map
  ? Omit<Map, V> & Record<V, [...Map[V], 0]>
  : Map & Record<V, [0]>;

type Count<T extends Item[], Map extends Record<Value, 0[]> = {}> = T extends [
  infer F,
  ...infer R extends Item[]
]
  ? [F] extends [never]
    ? Map
    : F extends Item[]
    ? Count<[...F, ...R], Map>
    : F extends Value
    ? Count<R, GetMap<F, Map>>
    : Map
  : Map;

type CountMap<T extends Record<Value, 0[]>> = {
  [K in keyof T]: T[K]["length"];
};

type CountElementNumberToObject<T extends Item[]> = CountMap<Count<T>>;

Solution by frontlich #28802

type DigsNext = { '0': '1', '1': '2', '2': '3', '3': '4', '4': '5', '5': '6', '6': '7', '7': '8', '8': '9' }
type AddOne<A extends number | string> = `${ A }` extends `${ infer AH }${ infer AT }`
  ? AH extends '9'
    ? `0${ AddOne<AT> }`
    : `${ DigsNext[AH & keyof DigsNext] }${ AT }`
  : '1'

type ToNumber<T> = T extends string | number
  ? `${ T }` extends `${ infer I extends number }` ? I : never
  : never

type ToArrayNumber<T, _R extends unknown[] = []> = T extends [ infer I, ...infer Rest ]
  ? [I] extends [number | string]
    ? `${ I }` extends `${ infer NI extends number }`
      ? ToArrayNumber<Rest, [ ..._R, NI ]>
      : never
    : ToArrayNumber<Rest, [ ..._R, I]>
  : _R

type CountElementNumberToObject<
  T extends unknown[],
  _R extends Record<number, number> = {},
> = ToArrayNumber<T> extends [ infer I, ...infer Rest ]
  ? [I] extends [number]
    ? CountElementNumberToObject<Rest, Omit<_R, I> & Record<I, ToNumber<AddOne<_R[I]>>>>
    : I extends unknown[]
      ? CountElementNumberToObject<[ ...I, ...Rest], _R>
      : {}
  : { [K in keyof _R]: _R[K] }

Solution by lvjiaxuan #28470

type Item = PropertyKey | Item[];

type CountOccurrences<
  Items extends unknown[],
  OccurrencesByKey extends Record<PropertyKey, 0[]> = {}
> = Items extends [infer Head, ...infer Tail extends Item[]]
  ? CountOccurrences<
      Tail,
      [Head] extends [never]
        ? OccurrencesByKey
        : Head extends PropertyKey
        ? {
            [Key in keyof OccurrencesByKey | Head]: Key extends Head
              ? Key extends keyof OccurrencesByKey
                ? [...OccurrencesByKey[Key], 0]
                : [0]
              : OccurrencesByKey[Key];
          }
        : Head extends Item[]
        ? CountOccurrences<Head, OccurrencesByKey>
        : never
    >
  : OccurrencesByKey;

type CountElementNumberToObject<ItemArray extends Item[]> =
  CountOccurrences<ItemArray> extends infer OccurrencesByKey extends Record<
    PropertyKey,
    0[]
  >
    ? { [Key in keyof OccurrencesByKey]: OccurrencesByKey[Key]["length"] }
    : never;

Solution by yevhenpavliuk #28421

type Flatten<T,R extends any[] = []> = 
  T extends [infer F,...infer L]?
    [F] extends [never]?
      Flatten<L,R>:
      F extends any[]?
        Flatten<L,[...R,...Flatten<F>]  >
        :Flatten<L,[...R,F]>
    :R 


type Count<
  T,
  R extends Record<string | number,any[]> = {}
> = 
T extends [infer F extends string | number,...infer L]?
  F extends keyof R?
    Count<L, Omit<R,F>& Record<F,[...R[F],0] > >
    : Count<L, R & Record<F,[0]>>
  :{
    [K in keyof R]:R[K]['length']
  }


type CountElementNumberToObject<
  T
> = 
  Count<Flatten<T>>

Solution by jiangshanmeta #28355

type Flatten<T extends unknown[]> = T extends [infer F, ...infer R]
  ? F extends unknown[]
    ? [...Flatten<F>, ...Flatten<R>]
    : [F, ...Flatten<R>]
  : []

// Get an initial object containing all the keys
type Map<T extends unknown[]> = {
  [K in T[number] as K extends string | number ? K : never]: []
}

// Core logic to iterate the tuple and recursively increment the mapped tuple assoicated with a specific key
type GetTupledObject<T extends unknown[], Dump extends Record<string | number, unknown[]> = Map<Flatten<T>>> =
  T extends [infer F, ...infer R]
    ? F extends unknown[]
      ? GetTupledObject<F, Dump>
      : F extends string | number
        ? GetTupledObject<R, {
          [P in keyof Dump]: P extends F
            ? [...Dump[P], unknown]
            : Dump[P]
        }>
        : {}
    : Dump

// Special case handling
// and count by each tuple's length
type CountElementNumberToObject<T extends unknown[]> =
  GetTupledObject<T> extends infer G
    ? [G] extends [never]
        ? {}
        : {
            [P in keyof G]: G[P] extends unknown[] ? G[P]['length'] : never
          }
    : never

Solution by jazelly #28320