# 5117-去除数组指定元素

# 题目描述

实现一个像 Lodash.without 函数一样的泛型 Without<T, U>,它接收数组类型的 T 和数字或数组类型的 U 为参数,会返回一个去除 U 中元素的数组 T。

例如:

type Res = Without<[1, 2], 1>; // expected to be [2]
type Res1 = Without<[1, 2, 4, 1, 5], [1, 2]>; // expected to be [4, 5]
type Res2 = Without<[2, 3, 2, 3, 2, 3, 2, 3], [2, 3]>; // expected to be []

# 分析

遍历元组,比较每一个元素同 U 中的元素是否相同来决定是否移除即可完成题目。

问题就变成了,元组 U 中是否存在遍历的元素 F,也就是 898-实现 Includes

但是第二个参数 U 不一定是元组,也有可能是单个元素,由于题目中都是数字,所以可以简单通过 U extends number ? [U] : U

# 题解

// 标准 Equal 判断逻辑,具体原因看 Equal判断 章节
type MyEqual<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B
  ? 1
  : 2
  ? true
  : false;

type Includes<T extends readonly any[], U> = T extends [infer F, ...infer R]
  ? MyEqual<F, U> extends true
    ? true
    : // 递归判断剩余元素
      Includes<R, U>
  : false;

type Without<T, U extends any[] | number> =
  // 匹配第一个元素
  T extends [infer F, ...infer R]
    ? // 判断 U 中是否包含 F
      Includes<U extends number ? [U] : U, F> extends true
      ? // 如果包含,则移除当前元素,直接递归剩余元素
        Without<R, U>
      : // 否则保留当前元素
        [F, ...Without<R, U>]
    : [];

当然,由于题目中指定了参数都是 number,所以 Includes 可以更加简化,直接判断即可,无需一定要实现 Equal。

# 知识点

  1. 元组遍历套路
  2. 898-实现 Includes
Last Updated: 2023/5/16 06:00:28