【问题标题】:How to use array.prototype.reduce() with TypeScript while having a boolean accumulator as the initial value?如何将 array.prototype.reduce() 与 TypeScript 一起使用,同时将布尔累加器作为初始值?
【发布时间】:2021-03-14 18:27:36
【问题描述】:

我打算在 binarysearch.io 上解决一些算法并遇到了这个问题:

我用JS解决了如下:

class Solution {
    solve(nums) {
        const Hash = {};
        const Cache = {};
        
        for (let val of nums) {
            if (!Hash[val]) {
                Hash[val] = 0;
            }
            Hash[val]++; //implicit else
        }

        const result = Object.values(Hash).reduce((accum, curr) => {
            if (accum && Cache[curr] !== 'unique') {
                Cache[curr] = 'unique';
                return true
            }
            return false;
        }, true);
        
        return result;
    }
}

但是,当我尝试使用我相当新的 TypeScript 来解决它时,我遇到了可能由 .reduce() 方法引起的编译错误:

class Solution {
    solve(nums: Array<number>): boolean {
        const Hash = {};
        const Cache = {};
        
        for (let val of nums) {
            if (!Hash[val]) {
                Hash[val] = 0;
            }
            Hash[val]++; //implicit else
        }
        
        const val_arr = Object.values(Hash);

        return val_arr.reduce((accum, curr) => {
            if (accum && Cache[curr] !== 'unique') {
                Cache[curr] = 'unique';
                return true;
            }
            return false;
        }, true);
    }
}

我不确定如何为 .reduce() 方法提供种子初始值的返回类型。我尝试将初始值更改为布尔类型,但仍然出现编译错误:

return val_arr.reduce((accum, curr) => {
            if (accum && Cache[curr] !== 'unique') {
                Cache[curr] = 'unique';
                return true;
            }
            return false;
        }, true as boolean);

我尝试搜索是否有其他人有此问题,但我发现的大多数帖子都将对象作为初始值,所以我无法弄清楚。似乎最简单的解决方案是在不使用 .reduce() 的情况下重构来解决这个问题,但我只是想知道如何创建与上述 ​​JS 解决方案“等效”的 TS。

【问题讨论】:

    标签: javascript typescript types static reduce


    【解决方案1】:

    你需要

    (1)正确键入Hash对象,使其key和value的类型能够被TS识别

    (2)正确键入Cache对象,使其key和value的类型能够被TS识别

    (3) 将累加器键入为boolean,而不是true,以便内部回调可以返回truefalse。 (这可以通过将 &lt;boolean&gt; 作为类型参数传递给 .reduce 来完成 - 使用泛型比 as 更可取)

    class Solution {
        solve(nums: Array<number>): boolean {
            const Hash: {[key: number]: number} = {};
            const Cache: {[key: number]: string} = {};
            
            for (let val of nums) {
                if (!Hash[val]) {
                    Hash[val] = 0;
                }
                Hash[val]++; //implicit else
            }
            
            const val_arr = Object.values(Hash);
    
            return val_arr.reduce<boolean>((accum, curr) => {
                if (accum && Cache[curr] !== 'unique') {
                    Cache[curr] = 'unique';
                    return true;
                }
                return false;
            }, true);
        }
    }
    

    要考虑的另一件事 - JavaScript 不是 Java。如果你有一个只包含一个方法的类,没有对实例变量的引用,那么在结构上定义一个普通函数会更有意义,例如:

    function solve(nums: Array<number>) {
      // function implementation
    }
    

    【讨论】:

    • 非常感谢!非常感谢您的帮助!
    猜你喜欢
    • 2015-12-15
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    相关资源
    最近更新 更多