21104-medium-findall

Back

type FindAll<T extends string, P extends string, U extends 1[] = []> = P extends '' ? [] : T extends `${string}${infer rest}` ? 
[
  ...(T extends `${P}${string}` ? [U['length']] : []),
  ...FindAll<rest, P, [...U, 1]>
] : []

Solution by ouzexi #34146

// your answers
type StringLength<T extends string, Res extends any[] = []> = T extends `${infer A}${infer R}` ? StringLength<R, [...Res, A]> : Res['length']

type SplitString<T extends string, Res extends any[] = []> = T extends `${infer A}${infer R}` ? [A, R] : T

type FindAll<T extends string, P extends string, Visit extends string = '', Res extends any[] = []> = 
  P extends '' ? [] :
    T extends `${infer A}${P}${infer R}` ? 
    SplitString<P> extends [infer X extends string, infer Y extends string] ? 
      FindAll<`${Y}${R}`, P, `${Visit}${A}${X}`, [...Res, StringLength<`${Visit}${A}`>]> 
      : FindAll<R, P, `${Visit}${A}${P}`, [...Res, StringLength<`${Visit}${A}`>]>
    : Res

Solution by heyuelan #33878

type FindAll<T extends string, P extends string, C extends any[] = [], U extends any[] = []> = P extends ""
  ? []
  : T extends `${string}${infer R}`
  ? T extends `${P}${string}`
    ? FindAll<R, P, [...C, 1], [...U, C["length"]]>
    : FindAll<R, P, [...C, 1], U>
  : U;

Solution by tototi5997 #33662

wrong solution when meet FindAll<'AAAA','AA'>


type StringLength<S, Arr extends any[] = []> = S extends `${string}${infer R}`
  ? StringLength<R, [...Arr, 1]>
  : Arr['length'];

type FindAll<
  T extends string,
  P extends string,
  PreStr = '',
  Ret extends number[] = []
> = P extends ''
  ? []
  : T extends `${infer Head}${P}${infer Tail}`
  ? FindAll<
      Tail,
      P,
      `${PreStr & string}${Head}${P}`,
      [...Ret, StringLength<`${PreStr & string}${Head}`>]
    >
  : Ret;

need to prase char one by one

type FindAll<
 T extends string,
 P extends string,
 PreStrArr extends any[]  =  [],
 Ret extends number[] = []
> = 
P extends ''
 ? []
 : T extends `${string}${infer R1}`
 		? T extends `${P}${infer _}` 
   				? FindAll<R1, P, [...PreStrArr, any], [...Ret, PreStrArr["length"]]>
   				: FindAll<R1, P, [...PreStrArr, any], Ret>
   		: Ret

Solution by sunupupup #33478

// your answers
type FirstCharOf<S extends string> = S extends `${infer C}${any}` ? C : ''
type LengthOf<S extends string, Result extends 0[] = []> = S extends `${any}${infer Rest}`
  ? LengthOf<Rest, [0, ...Result]>
  : Result['length']
type FindAll<T extends string, P extends string, Result extends number[] = [], Scanned extends string = ''> = P extends ''
  ? []
  : T extends `${Scanned}${infer Head}${P}${infer Tail}`
    ? FindAll<T, P, [...Result, LengthOf<`${Scanned}${Head}`>], `${Scanned}${Head}${FirstCharOf<P>}`>
    : Result

Solution by DevilTea #33257

// your answers
type Split<T extends string> = T extends `${infer FirstLetter}${infer Rest}` ? [FirstLetter, ...Split<Rest>] : [];
type StringLength<T extends string> = Split<T>['length'];
type Push<T extends any[], P = any> = [...T, P];
type NTuple<N extends number ,P extends any[] = []> = P['length'] extends N ? P : NTuple<N, Push<P, any>>;
type Add<T extends number, P extends number> = [...NTuple<T>, ...NTuple<P>]['length'];
type ToNumber<T> = T extends number ? T : never;

type RemoveFirstLetter<T extends string> = T extends `${infer F}${infer Rest}` ? Rest : '';

type FindAll<T extends string, P extends string, N extends number = 0> = 
  P extends ''
  ? []
  : T extends `${infer Front}${P}${infer Rest}` 
    ? [Add<StringLength<Front>, N>, ...FindAll<`${RemoveFirstLetter<P>}${Rest}`, P, ToNumber<Add<ToNumber<Add<N, 1>>, StringLength<Front>>>>] 
    : [];

Solution by kakasoo #32718

type LengthOfString<
  S extends string,
  T extends string[] = []
> = S extends `${infer F}${infer R}`
  ? LengthOfString<R, [...T, F]>
  : T["length"];

type FindAll<
  T extends string,
  P extends string,
  L extends string = ""
> = P extends ""
  ? []
  : T extends `${infer F}${P}${infer R}`
  ? P extends `${infer U}${infer V}`
    ? [LengthOfString<`${L}${F}`>, ...FindAll<`${V}${R}`, P, `${L}${F}${U}`>]
    : never
  : [];

Solution by vangie #32198

type FindAll<
  T extends string,
  P extends string,
  Before extends number[] = [],
> =
  P extends ''
    ? []
    : T extends `${infer _First}${infer Rest}`
      ? [
        ...(T extends `${P}${infer _Rest}` ? [Before['length']] : []),
        ...FindAll<Rest, P, [...Before, 0]>,
      ]
      : []

Solution by drylint #32078

// your answers

type GetStringLength<T extends string, C extends any[] = []> = T extends `${string}${infer O}` ? GetStringLength<O, [1, ...C]> : C['length'];
type FindAll<T extends string, P extends string, U extends string = ''> = P extends '' ? [] : 
  T extends `${U}${infer S}${P}${string}` ? [GetStringLength<`${U}${S}`>, ...FindAll<T, P, `${U}${S}${P extends `${infer O}${string}` ? O : ''}`>] : [];

Solution by tarotlwei #31749

type FindAll<
  T extends string,
  P extends string,
  L extends 0[] = [],
> = P extends ''
  ? []
  : T extends `${string}${infer R}`
    ? [
        ...(T extends `${P}${string}` ? [L['length']] : []),
        ...FindAll<R, P, [0, ...L]>,
      ]
    : []

Solution by FlareZh #31533

type FindAll<
  T extends string,
  P extends string,
  L extends unknown[] = [],
  R extends string = T extends `${string}${infer Rest}` ? Rest : ''
> = P extends ''
  ? []
  : T extends ''
  ? []
  : T extends `${P}${string}`
  ? [L['length'], ...FindAll<R, P, [...L, unknown]>]
  : FindAll<R, P, [...L, unknown]>;

Solution by bigcreate #31090

// your answers
type FindAll<T extends string, P extends string, Index extends unknown[] = []> = P extends '' ? [] : T extends `${infer F}${infer Rest}` ?[ ...(T extends `${P}${string}` ? [Index["length"]] : []), ...FindAll<Rest, P, [never, ...Index]>] : []

Solution by Kakeru-Miyazaki #30917

// your answers
// 拆分字符串
type Split<T extends string, S extends string = ''> = T extends `${infer P}${S}${infer L}`
 ? [P , ...Split<L, S>]
 : T extends '' ? [] : [T]

// 移除重复
type Deduplication<T, R extends any[] = [], M = never> = T extends [infer F, ...infer L]
  ? [F] extends [M]
    ? Deduplication<L, R, M>
    : Deduplication<L, [...R, F], M | F>
  : R

// 移除头部字符
type RemoveTheHead<T extends string> = T extends `${infer _}${infer S}` ? S : ''

type IndexOfAll<P extends unknown[], S extends string, T extends string, I extends [] = []> =
  T extends ''
    ? I
    : S extends `${infer F}${T}${infer _}`
      ? [...I, [...P, ...Split<F>]['length'], ...IndexOfAll<[...P, unknown], RemoveTheHead<S>, T, I>] // 递归逐步往后移动一步查找
      : I

type FindAll<T extends string, P extends string> = Deduplication<IndexOfAll<[], T, P>> // 移除重复

Solution by milletlovemouse #30902

type FindAll<T extends string, P extends string, U extends any[] = [], O extends any[] = []> = P extends '' ? O : T extends `${string}${infer B}` ? T extends `${P}${string}` ? FindAll<B, P, [...U, 0], [...O, U['length']]> : FindAll<B, P, [...U, 0], O> : O

Solution by dreamluo-plus #30694


type StrLength<T, Len extends unknown[] = []> = T extends `${string}${infer R}`
  ? StrLength<R, [...Len, unknown]>
  : Len['length']

type RemoveFirstWord<T> = T extends `${infer _}${infer L}` ? L : never

type FindAll<T extends string, P extends string, Arr extends number[] = []> = P extends ''
  ? []
  : T extends `${infer L}${P}${infer R}`
    ? FindAll<`${L}_${RemoveFirstWord<P>}${R}`, P, [...Arr, StrLength<L>]>
    : Arr

Solution by XkSuperCool #30355

This might look bit lengthy and probably isn't the smartest answer compared with the others but it should be east to understand. The main idea is to use the util type StrLen and SliceStr to get the same length characters of the target string type P from the original string type and check recursively.

// Get the length of the given string
type StrLen<S extends string, Len extends '🍎'[] = []> =
 S extends `${infer HEAD}${infer TAIL extends string}`
  ? StrLen<TAIL, [...Len, '🍎']>
  : Len['length']

type Test2110401 = StrLen<'aa'>  // 2
// Slice and return the first <Len> characeters of the given string
type SliceStr<S extends string, Len extends number, RES extends string = ''> =
  S extends `${infer HEAD}${infer TAIL extends string}`
    ? StrLen<RES> extends Len
      ? RES
      : SliceStr<TAIL, Len, `${RES}${HEAD}`>
    : RES

type Test2110402 = SliceStr<'abcde', 2> // ab
type FindAll<
  S extends string,
  P extends string,
  COUNT extends '🍎'[] = [],
  RES extends number[] = [],
> = P extends ''
  ? []
  : S extends `${infer HEAD}${infer TAIL extends string}`
  ? SliceStr<S, StrLen<P>> extends P
    ? FindAll<TAIL, P, [...COUNT, '🍎'], [...RES, COUNT['length']]>
    : FindAll<TAIL, P, [...COUNT, '🍎'], RES>
  : RES

Solution by playitsafe #30284

type StringLength<S> = S extends `${infer L}${infer E}` ? [L, ...StringLength<E>] : []
type RemoveFirst<S extends string> = S extends `${string}${infer R}` ? R: S
type FindAll<T extends string, P extends string, R extends any[] = [], Count extends any[] = []> =
  P extends ''
  ? [] : T extends `${infer L}${P}${infer E}`
    ? FindAll<`${RemoveFirst<P>}${E}`, P, [...R, [...Count, ...StringLength<L>]['length']], [...Count, ...StringLength<L>, 1]>
  : R

Solution by sv-98-maxin #30180

// 你的答案
type getStrL<T extends string, U extends ''[] = []> = T extends `${any}${infer R}` ? getStrL<R, [...U, '']> : U['length']
type FindAll<T extends string, P extends string, S extends string = '', R extends number[] = []> =
  P extends '' ? [] :
  T extends `${S}${infer F}${P}${any}` ?
  FindAll<T, P, `${S}${F}${P extends `${infer F}${any}` ? F : P}`, [...R, getStrL<`${S}${F}`>]>
  : R

Solution by YE840926098 #30145

type NormalFindAll<
  T extends string, 
  S extends string,
  P extends any[] = [],
  R extends number[] = [],
> = 
T extends `${string}${infer L}`?
  T extends `${S}${string}`?
    NormalFindAll<L,S,[...P,0],[...R,P['length']]>
    :NormalFindAll<L,S,[...P,0],R>
  :R

type FindAll<
  T extends string, 
  P extends string,
> = 
P extends ''?
  []:NormalFindAll<T,P>

Solution by jiangshanmeta #29712

type FindAll<T extends string, P extends string> = P extends '' ? [] : Helper<T, P>
type Helper<T extends string, P extends string, I extends 1[] = [], R extends number[] = []> =
  T extends ''
    ? R
    : T extends `${P}${string}`
      ? Helper<Tail<T>, P, [1, ...I], [...R, I['length']]>
      : Helper<Tail<T>, P, [1, ...I], R>
type Tail<T extends string> = T extends `${any}${infer Rest}` ? Rest : ''

Solution by Sun79 #29656