typescript递归数据结构的定义和处理

typescript是一种类型强约束的语言,一般来讲定义类型时都要明确指定类型的数据结构。而如果数据结构中涉及到不知道几层嵌套的递归时,就会有一些麻烦。

https://stackoverflow.com/questions/51657815/recursive-array-type-typescript

有一个回答说明了typescript中涉及到递归时的类型定义。

要点在于:要在类型内部增加自身的类型。

// 当你需要不确定末端节点的类型时,可以先定义一个Atom类型作为联合类型
type Atom = string | boolean | number
type NestedArray = Array<NestedArray | Atom>;
interface NestedArray extends Array<NestedArray | Atom> {}
// 当你确定末端节点的类型时,无需定义Atom类型,直接使用末端的类型即可
type RecursiveVector = Array<RecursiveVector | number>;
interface RecursiveVector extends Array<RecursiveVector | number> {}

如果需要更强的适应性,那就得使用模板

export interface NestedArray<T> extends Array<NestedArray<T> | T> {}

每次调用的时候,指定T的类型

在针对递归类型编写递归代码时,需要对当前递归的类型做判断:是否末端节点。如果是末端节点,则进行直接计算;如果不是末端节点,那么进入下一层递归。

比如说下面的代码用于求某两个递归数据结构中间比例的插值数值

function ArrayLinearInterpolation(startArray: RecursiveVector, endArray: RecursiveVector, param: number) {
    function tmpFun(startArray: RecursiveVector, endArray: RecursiveVector): RecursiveVector {
        if (!isArray(startArray) || !isArray(endArray)) {
            throw TypeError("startArray or endArray is not Array");
        }
        if (startArray.length != endArray.length) {
            throw TypeError("the dimension of startArray and endArray don't match");
        }
        let res: RecursiveVector = [];
        for (let j = 0; j < startArray.length; j++) {
            if (isNumber(startArray[j]) && isNumber(endArray[j])) {
                res.push((startArray[j] as number) + param * ((endArray[j] as number) - (startArray[j] as number)));
                continue;
            } else {
                res.push(tmpFun(startArray[j] as RecursiveVector, endArray[j] as RecursiveVector));
            }
        }
        return res;
    }
    return tmpFun(startArray, endArray);
}

返回值res必须定义为递归数据结构。在对递归数据进行节点末端判断后,再根据“是否末端”进行分别处理。

当针对末端调用递归函数进行处理时,必须用as指定末端数据类型,否则typescript在类型识别时会判断错误。当针对非末端调用递归函数进行处理时,也必须用as指定非末端的数据类型,否则typescript在类型识别时也会判断错误。

如果末端数据类型不是语言自带的数据类型,而是用户自定义的复杂类型,可以按照下面这个帖子的说明处理。

typescript递归遍历_ts 递归-CSDN博客

本质上来讲,就是在递归数据结构定义中,把子数据的类型定义为递归数据类型自身。最简单的递归数据是只包含自身,复杂的就要包含一些其他的数据。

这个有点类似于C++的链表。在C++中,某个链表数据类型中会有一个子数据是指针,该指针指向下一个同样的数据类型,当该指针为nullprt时,该链表结束。

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值