CountIf

Counts the number of elements in an array where a specified field matches a value using a comparison operator. Supports nested field paths and performs case-sensitive comparison.

Syntax

CountIf(array, fieldName, operator, value)

Parameters

  • array (array): The array of objects to count
  • fieldName (string): The field name or nested path to compare (e.g., “status” or “address.city”)
  • operator (string): The comparison operator: "==", "!=", "<", "<=", ">", ">="
  • value (any): The value to compare against

Returns

  • number: The count of elements where the specified field satisfies the comparison with the value

Description

The CountIf function searches through an array of objects and counts how many elements have a field that satisfies the comparison operator with the specified value. The function supports nested field paths using dot notation, allowing you to compare deeply nested properties.

Comparison operators enable powerful counting beyond simple equality: use "==" for equality, "!=" for inequality, "<", "<=", ">", ">=" for numeric comparisons. String comparisons are case-sensitive.

Non-object elements and objects with missing fields are skipped and not counted. Empty arrays return 0.

Examples

Equality comparison

var users = [
    { "name": "Alice", "status": "active" },
    { "name": "Bob", "status": "inactive" },
    { "name": "Carol", "status": "active" },
    { "name": "Dan", "status": "active" }
]

var activeCount = CountIf(users, "status", "==", "active")
# activeCount is 3

Inequality comparison

var tickets = [
    { "id": 1, "status": "open" },
    { "id": 2, "status": "closed" },
    { "id": 3, "status": "open" },
    { "id": 4, "status": "pending" }
]

var notClosed = CountIf(tickets, "status", "!=", "closed")
# notClosed is 3

Numeric comparison

var orders = [
    { "id": 1, "quantity": 5, "priority": 1 },
    { "id": 2, "quantity": 10, "priority": 2 },
    { "id": 3, "quantity": 5, "priority": 1 },
    { "id": 4, "quantity": 15, "priority": 1 }
]

var highPriorityCount = CountIf(orders, "priority", "==", 1)
# highPriorityCount is 3

var largeOrders = CountIf(orders, "quantity", ">", 5)
# largeOrders is 2

var mediumPriority = CountIf(orders, "priority", "<=", 2)
# mediumPriority is 4

Nested path comparison

var employees = [
    { "name": "Alice", "address": { "city": "New York" } },
    { "name": "Bob", "address": { "city": "Los Angeles" } },
    { "name": "Carol", "address": { "city": "New York" } },
    { "name": "Dan", "address": { "city": "Chicago" } }
]

var nyCount = CountIf(employees, "address.city", "==", "New York")
# nyCount is 2

Boolean field comparison

var tasks = [
    { "title": "Task 1", "completed": true },
    { "title": "Task 2", "completed": false },
    { "title": "Task 3", "completed": true },
    { "title": "Task 4", "completed": true }
]

var completedCount = CountIf(tasks, "completed", "==", true)
# completedCount is 3

var incompleteCount = CountIf(tasks, "completed", "!=", true)
# incompleteCount is 1

Counting null values

var records = [
    { "id": 1, "email": "alice@example.com" },
    { "id": 2, "email": null },
    { "id": 3, "email": "bob@example.com" },
    { "id": 4, "email": null }
]

var missingEmailCount = CountIf(records, "email", "==", null)
# missingEmailCount is 2

var hasEmailCount = CountIf(records, "email", "!=", null)
# hasEmailCount is 2

Building summary statistics

var tickets = [
    { "id": 1, "severity": "high", "status": "open" },
    { "id": 2, "severity": "low", "status": "closed" },
    { "id": 3, "severity": "high", "status": "open" },
    { "id": 4, "severity": "medium", "status": "open" },
    { "id": 5, "severity": "high", "status": "closed" }
]

Data = {
    "totalTickets": Length(tickets),
    "highSeverity": CountIf(tickets, "severity", "==", "high"),
    "openTickets": CountIf(tickets, "status", "==", "open"),
    "closedTickets": CountIf(tickets, "status", "==", "closed")
}
# Result: { "totalTickets": 5, "highSeverity": 3, "openTickets": 3, "closedTickets": 2 }

Combining with Filter

var incidents = [
    { "id": 1, "team": "IT", "priority": 1, "status": "open" },
    { "id": 2, "team": "IT", "priority": 2, "status": "closed" },
    { "id": 3, "team": "HR", "priority": 1, "status": "open" },
    { "id": 4, "team": "IT", "priority": 1, "status": "open" }
]

var criticalOpen = CountIf(
    Filter(incidents, "priority", "==", 1),
    "status", "!=", "closed"
)
# criticalOpen is 3

Dynamic counting across categories

var products = [
    { "name": "Widget A", "category": "tools" },
    { "name": "Widget B", "category": "parts" },
    { "name": "Widget C", "category": "tools" },
    { "name": "Widget D", "category": "accessories" }
]

var categories = ["tools", "parts", "accessories"]
var categoryCounts = []

foreach category in categories do
    var count = CountIf(products, "category", "==", category)
    Append(categoryCounts, { "category": category, "count": count })
end

# categoryCounts = [
#   { "category": "tools", "count": 2 },
#   { "category": "parts", "count": 1 },
#   { "category": "accessories", "count": 1 }
# ]

Notes

  • Supported operators: "==", "!=", "<", "<=", ">", ">="
  • String comparisons are case-sensitive. “Active” and “active” are treated as different values
  • For case-insensitive comparison, normalize values using the Lower() function before comparison
  • Non-object elements in the array are skipped and not counted
  • Objects missing the specified field are skipped and not counted
  • Nested paths traverse objects using dot notation (e.g., “user.profile.age”)
  • Empty arrays always return 0
  • Can be combined with Filter to count elements in a filtered subset

Back to top

Copyright © Mesch Systems. All rights reserved.