减少一组谓词函数
Reducing a set of predicate functions
我有一组谓词进入我们将调用的函数 searchForAcceptableNumber
。
searchForAcceptableNumber(arrayOfNumbers: number[], ...isNumberAcceptablePredicates: Array<(aNumber: number) => boolean>): number[] {
const acceptableNumbers: number[] = [];
const isNumberAcceptablePredicate: (aNumber: number) => boolean = (aNumber: number) => {
const isLabelAcceptableReducer = (accumulator, currentValue) => accumulator && currentValue(aNumber);
return isNumberAcceptablePredicates.reduce(isLabelAcceptableReducer);
};
arrayOfNumbers.forEach((aNumber: number) => {
if (isNumberAcceptablePredicate(aNumber)) {
acceptableNumbers.push(aNumber);
}
});
return acceptableNumbers;
}
你懂的。从本质上讲,它遍历了一切,一切都很好……除了 isNumberAcceptablePredicate
不断收到类型 (aNumber: number) => (aNumber: number) => boolean
的错误这一事实。我可以摆脱类型,它会全部编译并工作得很好。奇怪的是,如果我在调试会话期间将鼠标悬停在 isNumberAcceptablePredicate
上,它说它确实是 (aNumber: number) => boolean
.
类型
这不一定是代码破坏,也就是说,我最终将这个谓词传递给需要类型 (aNumber: number) => boolean
的其他函数,因此它确实引入了代码破坏并增加了限制。我确定我错过了一些荒谬的东西,我只是不知道是什么。
您只需要为 reduce 函数提供一个初始值,否则它默认使用数组中的第一个元素作为初始值,其类型为 (aNumber: number) => boolean
而不是 boolean
function searchForAcceptableNumber(
arrayOfNumbers: number[],
...isNumberAcceptablePredicates: Array<(aNumber: number) => boolean>
): number[] {
const acceptableNumbers: number[] = []
const isNumberAcceptablePredicate: (aNumber: number) => boolean = (
aNumber: number,
) => {
const isLabelAcceptableReducer = (accumulator, currentValue) =>
accumulator && currentValue(aNumber)
return isNumberAcceptablePredicates.reduce(isLabelAcceptableReducer, true) // <-- initialise to true
}
arrayOfNumbers.forEach((aNumber: number) => {
if (isNumberAcceptablePredicate(aNumber)) {
acceptableNumbers.push(aNumber)
}
})
return acceptableNumbers
}
您还可以使用一些内置的数组函数来大大缩短此函数,例如
function searchForAcceptableNumber(
arrayOfNumbers: number[],
...isNumberAcceptablePredicates: Array<(aNumber: number) => boolean>
): number[] {
return arrayOfNumbers.filter(number =>
isNumberAcceptablePredicates.every(predicate => predicate(number)),
)
}
如果您想概括实施,您可以执行以下操作
function filterList<T>(
values: T[],
predicates: Array<(val: T) => boolean>,
): T[] {
return values.filter(val => predicates.every(pred => pred(val)))
}
你也可以使用箭头函数,因为函数只返回一个值,有些人更喜欢它的简洁性
const filterList = <T extends any>(
values: T[],
predicates: Array<(val: T) => boolean>,
): T[] => values.filter(val => predicates.every(pred => pred(val)))
注:<T extends any>
的原因虽然extends any
在语义上是多余的,但还是有必要的,因为单独的<T>
在句法上是有歧义的,可能被视为JSX
标签
我有一组谓词进入我们将调用的函数 searchForAcceptableNumber
。
searchForAcceptableNumber(arrayOfNumbers: number[], ...isNumberAcceptablePredicates: Array<(aNumber: number) => boolean>): number[] {
const acceptableNumbers: number[] = [];
const isNumberAcceptablePredicate: (aNumber: number) => boolean = (aNumber: number) => {
const isLabelAcceptableReducer = (accumulator, currentValue) => accumulator && currentValue(aNumber);
return isNumberAcceptablePredicates.reduce(isLabelAcceptableReducer);
};
arrayOfNumbers.forEach((aNumber: number) => {
if (isNumberAcceptablePredicate(aNumber)) {
acceptableNumbers.push(aNumber);
}
});
return acceptableNumbers;
}
你懂的。从本质上讲,它遍历了一切,一切都很好……除了 isNumberAcceptablePredicate
不断收到类型 (aNumber: number) => (aNumber: number) => boolean
的错误这一事实。我可以摆脱类型,它会全部编译并工作得很好。奇怪的是,如果我在调试会话期间将鼠标悬停在 isNumberAcceptablePredicate
上,它说它确实是 (aNumber: number) => boolean
.
这不一定是代码破坏,也就是说,我最终将这个谓词传递给需要类型 (aNumber: number) => boolean
的其他函数,因此它确实引入了代码破坏并增加了限制。我确定我错过了一些荒谬的东西,我只是不知道是什么。
您只需要为 reduce 函数提供一个初始值,否则它默认使用数组中的第一个元素作为初始值,其类型为 (aNumber: number) => boolean
而不是 boolean
function searchForAcceptableNumber(
arrayOfNumbers: number[],
...isNumberAcceptablePredicates: Array<(aNumber: number) => boolean>
): number[] {
const acceptableNumbers: number[] = []
const isNumberAcceptablePredicate: (aNumber: number) => boolean = (
aNumber: number,
) => {
const isLabelAcceptableReducer = (accumulator, currentValue) =>
accumulator && currentValue(aNumber)
return isNumberAcceptablePredicates.reduce(isLabelAcceptableReducer, true) // <-- initialise to true
}
arrayOfNumbers.forEach((aNumber: number) => {
if (isNumberAcceptablePredicate(aNumber)) {
acceptableNumbers.push(aNumber)
}
})
return acceptableNumbers
}
您还可以使用一些内置的数组函数来大大缩短此函数,例如
function searchForAcceptableNumber(
arrayOfNumbers: number[],
...isNumberAcceptablePredicates: Array<(aNumber: number) => boolean>
): number[] {
return arrayOfNumbers.filter(number =>
isNumberAcceptablePredicates.every(predicate => predicate(number)),
)
}
如果您想概括实施,您可以执行以下操作
function filterList<T>(
values: T[],
predicates: Array<(val: T) => boolean>,
): T[] {
return values.filter(val => predicates.every(pred => pred(val)))
}
你也可以使用箭头函数,因为函数只返回一个值,有些人更喜欢它的简洁性
const filterList = <T extends any>(
values: T[],
predicates: Array<(val: T) => boolean>,
): T[] => values.filter(val => predicates.every(pred => pred(val)))
注:<T extends any>
的原因虽然extends any
在语义上是多余的,但还是有必要的,因为单独的<T>
在句法上是有歧义的,可能被视为JSX
标签