Angular BMI统计管道异常:无法返回BMI≥30的数组元素数量
Let's break down why your pipe isn't returning the expected count of 4 and fix it step by step:
Key Issues in Your Current Code
Incorrect Value Comparison
You're directly comparing the entire object (items[i]) to the number 30. Since each element in your array is an object like{ "bmi": 34.32 }, JavaScript converts objects toNaNwhen comparing to numbers.NaN >= 30always evaluates tofalse, so your counter never increments.Unused & Missing Parameter
Yourtransformmethod defines a second parameterattr, but you don't use it in the logic, and you also don't pass it in your template ({{ bmis | bmi }}). While Angular allows missing parameters, this adds unnecessary confusion here.
Fixed Pipe Implementation
Option 1: Pipe Specific to BMI Count
If you only need this pipe for counting BMI values >=30, simplify it to directly target the bmi property:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'bmiCount' }) // Renamed for clarity export class BmiCountPipe implements PipeTransform { transform(items: { bmi: number }[]): number { // Guard clause to handle null/undefined input if (!items) return 0; // Use array filter to get matching items, then return the length return items.filter(item => item.bmi >= 30.0).length; } }
Update your template to use the new pipe name:
{{ bmis | bmiCount }}
Option 2: Generic Pipe for Any Attribute & Threshold
If you want a reusable pipe that works with different attributes and thresholds, adjust it to accept and use the parameters:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'attributeThresholdCount' }) export class AttributeThresholdCountPipe implements PipeTransform { transform(items: any[], attribute: string, threshold: number = 30): number { // Guard clauses to avoid errors with invalid input if (!items || !attribute) return 0; return items.filter(item => item[attribute] >= threshold).length; } }
Use it in your template like this (passing the bmi attribute and threshold):
{{ bmis | attributeThresholdCount:'bmi':30 }}
Why This Works
With either fix, we now correctly access the bmi property of each object in the array. Using filter is more concise than a for-loop, and adding guard clauses prevents errors if the input array is null or undefined.
Testing with your sample array:bmis = [ { "bmi": 34.32 }, { "bmi": 23.75 }, { "bmi": 19.06 }, { "bmi": 18.69 }, { "bmi": 45.40 }, { "bmi": 37.64 }, { "bmi": 35.54 } ]
The pipe will count the 4 items with BMI >=30, returning the expected result of 4.
内容的提问来源于stack exchange,提问作者Fabian

