Skip to main content
Version: v2.2.82 (latest)
Recipes · 07 / 17

Filtering and Mapping

Filter and map collections effectively using fp-go's array operations for clean, composable data processing.

01

Basic Filtering

Filter elements based on predicates to select only the items you need.

basic-filtering.go
package main

import (
  "fmt"
  
  A "github.com/IBM/fp-go/v2/array"
)

func main() {
  numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
  
  // Filter even numbers
  evens := A.Filter(func(n int) bool {
      return n%2 == 0
  })(numbers)
  
  fmt.Printf("Even numbers: %v\n", evens)
  // Output: Even numbers: [2 4 6 8 10]
  
  // Filter numbers greater than 5
  greaterThan5 := A.Filter(func(n int) bool {
      return n > 5
  })(numbers)
  
  fmt.Printf("Greater than 5: %v\n", greaterThan5)
  // Output: Greater than 5: [6 7 8 9 10]
}
02

Basic Mapping

Transform elements in a collection by applying a function to each item.

basic-mapping.go
package main

import (
  "fmt"
  "strings"
  
  A "github.com/IBM/fp-go/v2/array"
)

func main() {
  words := []string{"hello", "world", "functional", "programming"}
  
  // Convert to uppercase
  uppercase := A.Map(strings.ToUpper)(words)
  fmt.Printf("Uppercase: %v\n", uppercase)
  // Output: Uppercase: [HELLO WORLD FUNCTIONAL PROGRAMMING]
  
  // Get lengths
  lengths := A.Map(func(s string) int {
      return len(s)
  })(words)
  fmt.Printf("Lengths: %v\n", lengths)
  // Output: Lengths: [5 5 10 11]
}
03

Filter and Map Combined

Chain filtering and mapping operations for powerful data transformations.

filter-map-combined.go
package main

import (
  "fmt"
  "strings"
  
  A "github.com/IBM/fp-go/v2/array"
  F "github.com/IBM/fp-go/v2/function"
)

type Product struct {
  Name  string
  Price float64
  Stock int
}

func main() {
  products := []Product{
      {Name: "Apple", Price: 1.50, Stock: 10},
      {Name: "Banana", Price: 0.75, Stock: 0},
      {Name: "Cherry", Price: 2.00, Stock: 5},
      {Name: "Date", Price: 3.00, Stock: 0},
  }
  
  // Get names of in-stock products under $2
  result := F.Pipe2(
      products,
      A.Filter(func(p Product) bool {
          return p.Stock > 0 && p.Price < 2.00
      }),
      A.Map(func(p Product) string {
          return strings.ToUpper(p.Name)
      }),
  )
  
  fmt.Printf("Available affordable products: %v\n", result)
  // Output: Available affordable products: [APPLE]
}
04

FilterMap - Filter and Transform

Filter and transform in a single operation for better performance.

filtermap.go
package main

import (
  "fmt"
  "strconv"
  
  A "github.com/IBM/fp-go/v2/array"
  O "github.com/IBM/fp-go/v2/option"
)

// Parse string to int, returning None for invalid strings
func parseInt(s string) O.Option[int] {
  val, err := strconv.Atoi(s)
  if err != nil {
      return O.None[int]()
  }
  return O.Some(val)
}

func main() {
  inputs := []string{"1", "abc", "2", "def", "3", "4"}
  
  // Parse and filter valid integers
  numbers := A.FilterMap(parseInt)(inputs)
  
  fmt.Printf("Valid numbers: %v\n", numbers)
  // Output: Valid numbers: [1 2 3 4]
}
05

Partition - Split by Predicate

Split a collection into two based on a predicate—one for matches, one for non-matches.

partition.go
package main

import (
  "fmt"
  
  A "github.com/IBM/fp-go/v2/array"
)

func main() {
  numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
  
  // Partition into evens and odds
  evens, odds := A.Partition(func(n int) bool {
      return n%2 == 0
  })(numbers)
  
  fmt.Printf("Evens: %v\n", evens)
  fmt.Printf("Odds: %v\n", odds)
  // Output:
  // Evens: [2 4 6 8 10]
  // Odds: [1 3 5 7 9]
}
06

Complex Filtering

Use multiple conditions and custom logic for sophisticated filtering.

complex-filtering.go
package main

import (
  "fmt"
  "strings"
  
  A "github.com/IBM/fp-go/v2/array"
)

type User struct {
  Name   string
  Age    int
  Active bool
  Role   string
}

func main() {
  users := []User{
      {Name: "Alice", Age: 25, Active: true, Role: "admin"},
      {Name: "Bob", Age: 17, Active: true, Role: "user"},
      {Name: "Charlie", Age: 30, Active: false, Role: "user"},
      {Name: "Diana", Age: 22, Active: true, Role: "user"},
  }
  
  // Find active adult users
  activeAdults := A.Filter(func(u User) bool {
      return u.Active && u.Age >= 18
  })(users)
  
  fmt.Println("Active adult users:")
  for _, u := range activeAdults {
      fmt.Printf("  - %s (%d)\n", u.Name, u.Age)
  }
  
  // Find admins or users over 25
  privileged := A.Filter(func(u User) bool {
      return u.Role == "admin" || u.Age > 25
  })(users)
  
  fmt.Println("\nPrivileged users:")
  for _, u := range privileged {
      fmt.Printf("  - %s (%s)\n", u.Name, u.Role)
  }
}
07

Best Practices

Steps
  • Use Filter before Map — Reduce data early to improve performance

    required
  • Use FilterMap — When filtering and mapping, use FilterMap for efficiency

    required
  • Keep predicates pure — No side effects in filter functions

    required
  • Keep mappers pure — No side effects in map functions

    required
  • Use Partition — When you need both filtered and rejected items

    recommended
  • Compose operations — Chain multiple filters and maps for clarity

    optional