Topic 13 of 28 · Android Native Developer

Topic 13 : Operators on Collections

Lesson TL;DRTopic 13: Operators on Collections 📖 6 min read · 🎯 advanced · 🧭 Prerequisites: customuicomponents, applicationarchitectureusingmvcmvpmvvmeachtopiccoveredononeday Why this matters Up until now, you...
6 min read·advanced·collections · javascript · python · array-methods

Topic 13: Operators on Collections

📖 6 min read · 🎯 advanced · 🧭 Prerequisites: custom-ui-components, application-architecture-using-mvcmvpmvvm-each-topic-covered-on-one-day

Why this matters

Up until now, you've been storing data in lists and arrays — but storing data is only half the job. The real work is shaping it: pulling out only what you need, transforming every item, finding a specific one, or collapsing a whole list into a single answer. Think about the last time you scrolled through a food-delivery app and filtered by "under 30 minutes" or sorted by rating — that's exactly what operators like filter, map, sort, and reduce do under the hood. In this lesson, you'll learn to stop looping through collections by hand and start using Kotlin's built-in operators to do that work cleanly and in far fewer lines.

What You'll Learn

  • Apply JavaScript array methods (forEach, map, filter, reduce, find, some, every, sort, reverse) to transform and query collections
  • Apply equivalent Python operations using built-ins (map, filter, reduce, any, all, sorted, reversed) and generator expressions
  • Recognize the structural similarities between JavaScript and Python collection operators
  • Identify the key differences in how each language exposes these operations (prototype methods vs. built-in functions)

The Analogy

Think of a collection as a conveyor belt in a factory full of products rolling past. forEach is a worker who inspects every item but changes nothing. map is a spray-painter who repaints each item and puts a brand-new version on a second belt. filter is a quality inspector who only lets certain items through the gate. reduce is an accountant at the end of the line who tallies everything into one final number. find is the first inspector who raises a hand the moment a qualifying item rolls by and stops watching after that. sort and reverse are the logistics crew who reorder the belt entirely before it even starts moving.

Chapter 1: Operators on Collections in JavaScript

JavaScript arrays ship with a rich set of prototype methods that let you express data transformations declaratively. Create a file called collections.js and work through each method below.

collections.js

// Example array
let numbers = [1, 2, 3, 4, 5];

// forEach: Executes a function for each element — no return value
numbers.forEach((number) => {
    console.log(number);
});

// map: Creates a new array with the results of calling a function on every element
let squares = numbers.map((number) => number * number);
console.log(squares); // [1, 4, 9, 16, 25]

// filter: Creates a new array with all elements that pass the test
let evenNumbers = numbers.filter((number) => number % 2 === 0);
console.log(evenNumbers); // [2, 4]

// reduce: Executes a reducer function on each element, resulting in a single output value
let sum = numbers.reduce((total, number) => total + number, 0);
console.log(sum); // 15

// find: Returns the first element that passes the test
let firstEvenNumber = numbers.find((number) => number % 2 === 0);
console.log(firstEvenNumber); // 2

// some: Checks if at least one element passes the test
let hasNegativeNumbers = numbers.some((number) => number < 0);
console.log(hasNegativeNumbers); // false

// every: Checks if all elements pass the test
let allPositive = numbers.every((number) => number > 0);
console.log(allPositive); // true

// sort: Sorts the elements of an array — spread first to avoid mutating the original
let sortedNumbers = [...numbers].sort((a, b) => b - a);
console.log(sortedNumbers); // [5, 4, 3, 2, 1]

// reverse: Reverses the order of the elements in an array
let reversedNumbers = [...numbers].reverse();
console.log(reversedNumbers); // [5, 4, 3, 2, 1]

Run the file:

node collections.js

Method reference at a glance

MethodReturnsMutates original?
forEachundefinedNo
mapNew arrayNo
filterNew array (subset)No
reduceSingle valueNo
findFirst match or undefinedNo
someBooleanNo
everyBooleanNo
sortSorted array (in-place!)Yes — spread first
reverseReversed array (in-place!)Yes — spread first

sort and reverse mutate the original array by default. The spread operator ([...numbers]) creates a shallow copy so the source array stays intact — a critical habit in production code.

Chapter 2: Operators on Collections in Python

Python achieves the same results through a combination of built-in functions, the functools module, and generator expressions. Create collections.py and walk through each operation.

collections.py

# Example list
numbers = [1, 2, 3, 4, 5]

# forEach equivalent: Iterating through each element with a for loop
for number in numbers:
    print(number)

# map: Creating a new list with the results of calling a function on every element
squares = list(map(lambda x: x * x, numbers))
print(squares)  # [1, 4, 9, 16, 25]

# filter: Creating a new list with all elements that pass the test
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # [2, 4]

# reduce: Applying a reducer function to each element, resulting in a single output value
from functools import reduce
sum_of_numbers = reduce(lambda total, x: total + x, numbers)
print(sum_of_numbers)  # 15

# find: Finding the first element that passes the test
# Uses next() with a generator expression; returns None if nothing matches
first_even_number = next((x for x in numbers if x % 2 == 0), None)
print(first_even_number)  # 2

# some equivalent: Checking if at least one element passes the test (using any)
has_negative_numbers = any(x < 0 for x in numbers)
print(has_negative_numbers)  # False

# every equivalent: Checking if all elements pass the test (using all)
all_positive = all(x > 0 for x in numbers)
print(all_positive)  # True

# sort: Sorting the elements of a list — sorted() returns a new list, does not mutate
sorted_numbers = sorted(numbers, reverse=True)
print(sorted_numbers)  # [5, 4, 3, 2, 1]

# reverse: Reversing the order of the elements in a list
reversed_numbers = list(reversed(numbers))
print(reversed_numbers)  # [5, 4, 3, 2, 1]

Run the file:

python collections.py

Key Python idioms to remember

  • map() and filter() return iterators in Python 3 — wrap them in list() to get a concrete list.
  • reduce is not a built-in in Python 3; import it from functools.
  • sorted() always returns a new list; the original is untouched. This is the opposite default from JavaScript's Array.prototype.sort.
  • reversed() returns an iterator; wrap in list() to materialize it.
  • Generator expressions (x for x in numbers if ...) are Python's idiomatic, lazy alternative to filter — pair with next() for a find-style lookup.

Chapter 3: Comparing JavaScript and Python Collection Operators

the trainer pulled up a side-by-side chart on the chamber screen to close out the session.

Similarities

  • Both JavaScript and Python offer ways to iterate over every element in a collection (forEach in JavaScript; a for loop in Python).
  • Both provide map — create a new collection by applying a transformation function to each element.
  • Both provide filter — produce a sub-collection containing only elements that satisfy a condition.
  • Both provide reduce — aggregate a collection down to a single value using an accumulator.
  • Both languages support sorting and reversing collections.

Differences

  • JavaScript exposes find, some, and every directly as array prototype methods. Python uses next() with a generator expression for find, and the built-in functions any() / all() for some / every.
  • JavaScript's Array.prototype.sort and Array.prototype.reverse mutate the original array. Python's sorted() and reversed() are non-mutating and return new objects.
  • Python's reduce lives in functools (not a built-in), reflecting the language's preference for explicit for loops over functional reduction chains.
  • Python's map and filter return lazy iterators; JavaScript's return fully realized arrays immediately.
graph LR
    subgraph JavaScript
        J1[forEach] --> J2[map]
        J2 --> J3[filter]
        J3 --> J4[reduce]
        J4 --> J5[find / some / every]
        J5 --> J6[sort / reverse — mutates!]
    end
    subgraph Python
        P1[for loop] --> P2[map + list]
        P2 --> P3[filter + list]
        P3 --> P4[reduce from functools]
        P4 --> P5[next + generator / any / all]
        P5 --> P6[sorted / reversed — non-mutating]
    end
    J1 -.equivalent.- P1
    J2 -.equivalent.- P2
    J3 -.equivalent.- P3
    J4 -.equivalent.- P4
    J5 -.equivalent.- P5
    J6 -.equivalent.- P6

🧪 Try It Yourself

Task: Given the array/list [3, 17, -4, 9, 0, -1, 42, 8], produce two results:

  1. A new collection containing only the positive numbers (strictly greater than 0), each squared.
  2. The sum of those squared positives.

Success criterion: Running your file should print [9, 289, 81, 1764, 64] and 2207 to the console (order may vary depending on language sort behavior — the sum is the canonical check).

JavaScript starter:

const data = [3, 17, -4, 9, 0, -1, 42, 8];

const squaredPositives = data
  .filter((n) => n > 0)
  .map((n) => n * n);

const total = squaredPositives.reduce((acc, n) => acc + n, 0);

console.log(squaredPositives);
console.log(total);

Python starter:

from functools import reduce

data = [3, 17, -4, 9, 0, -1, 42, 8]

squared_positives = list(map(lambda x: x * x, filter(lambda x: x > 0, data)))
total = reduce(lambda acc, x: acc + x, squared_positives)

print(squared_positives)
print(total)

🔍 Checkpoint Quiz

Q1. In JavaScript, why should you write [...numbers].sort(...) instead of numbers.sort(...) when you want to keep the original array intact?

A) sort returns undefined without the spread
B) sort mutates the array in place; spreading creates a shallow copy first
C) The spread operator is required syntax for the comparator callback
D) sort only works on copies of arrays, never originals

Q2. What does the following Python snippet print?

data = [10, 3, 7, 1, 9]
result = next((x for x in data if x < 5), -1)
print(result)

A) 1
B) 3
C) -1
D) [3, 1]

Q3. Given this JavaScript code, what is the value of output?

const values = [2, 4, 6, 8];
const output = values.every((v) => v % 2 === 0);

A) [2, 4, 6, 8]
B) 4
C) false
D) true

Q4. You have a Python list of order totals and need to flag whether any order exceeds $500. Which built-in best fits this task, and why?

A) all() — it confirms every order is valid
B) any() — it short-circuits and returns True the moment one match is found
C) filter() — it returns all matching orders
D) next() — it returns the first exceeding value

A1. B — Array.prototype.sort mutates the array in place. Spreading into a new array first ensures the source collection is unchanged, which is essential when the original order still matters downstream.

A2. B — The generator expression yields 3 as the first element less than 5. next() returns it immediately without scanning the rest of the list.

A3. D — every returns true only if the callback returns true for all elements. All four values are even, so output is true.

A4. B — any() is the idiomatic choice. It short-circuits on the first True result, making it efficient even on large datasets. filter() would work but materializes all matches unnecessarily when you only need a boolean answer.

🪞 Recap

  • JavaScript arrays expose forEach, map, filter, reduce, find, some, every, sort, and reverse directly as prototype methods.
  • Python achieves the same results via built-in functions (map, filter, any, all, sorted, reversed), functools.reduce, and generator expressions with next().
  • JavaScript's sort and reverse mutate the original array; Python's sorted() and reversed() are non-mutating — a critical behavioral difference.
  • Both languages share the same conceptual model: iterate, transform, filter, aggregate, find, check, reorder.
  • Mastering these operators is foundational for writing clean, declarative data-manipulation code in any collection-heavy application.

📚 Further Reading

Like this topic? It’s one of 28 in Android Native Developer.

Block your seat for ₹2,500 and join the next cohort.