Skip to content

Instantly share code, notes, and snippets.

@mfonism
Last active April 21, 2024 19:02
Show Gist options
  • Save mfonism/4d359da941d0d570d057d77b2c84e38b to your computer and use it in GitHub Desktop.
Save mfonism/4d359da941d0d570d057d77b2c84e38b to your computer and use it in GitHub Desktop.
Elm Homework for Friends at Hamelin

PREV: Map it like it's hot!
NEXT:


Filter like a Real star!

Filtering is a powerful feature in functional programming that allows you to refine and manipulate datasets efficiently, ensuring that only elements meeting specific criteria are retained for further processing.

Throughout this series, you will encounter various scenarios that challenge you to apply List.filter. Each exercise is crafted to help you deepen your grasp of list transformations and to gain familiarity with Elm's strong type system and functional programming paradigm.

Goals of the Series:

  • Understand the Basics: Learn how to use List.filter to apply simple conditions to data.
  • Handle Complex Data Structures: Practice filtering data that includes custom types and nested structures.
  • Develop Problem-Solving Skills: Each exercise provides a unique problem scenario encouraging you to think critically about how to apply filtering effectively.
  • Enhance Code Clarity and Safety: Emphasize writing clear and maintainable code using Elm’s type system.

Instructions for Exercises:

  • Each exercise will provide a dataset and a task focusing on a specific filtering challenge.
  • Think critically about the conditions under which data should be included in your result.
  • Try to use Elm’s custom types where applicable to improve type safety and code readability.

By the end of this series, you should feel confident in your ability to manipulate and filter data effectively using Elm, preparing you for more advanced programming tasks and real-world applications.


Exercise 1: Filter Even Numbers

Task: Write a function to filter out all even numbers from a list of integers.

Example Inputs and Outputs

  • Input: [1, 2, 3, 4, 5, 6, 7, 8]
    Output: [1, 3, 5, 7]
  • Input: [12, 14, 15, 19, 20, 21]
    Output: [15, 19, 21]
  • Input: [2, 4, 6, 8, 10]
    Output: []
  • Input: [11, 22, 33, 44, 55]
    Output: [11, 33, 55]

Exercise 2: Filter Short Words

Task: Create a function to exclude words shorter than 4 characters from a list of strings.

Example Inputs and Outputs

  • Input: ["apple", "is", "good", "for", "you"]
    Output: ["apple", "good"]
  • Input: ["elm", "is", "fun", "to", "learn"]
    Output: ["learn"]
  • Input: ["chat", "at", "openai", "with", "gpt"]
    Output: ["chat", "openai", "with"]
  • Input: ["this", "is", "a", "list", "of", "words"]
    Output: ["this", "list", "words"]

Exercise 3: Filter High Scores

Task: Develop a function to filter out scores below 75 from a list of student scores.

Example Inputs and Outputs

  • Input: [70, 82, 89, 90, 55, 78]
    Output: [82, 89, 90, 78]
  • Input: [60, 73, 69, 85, 91]
    Output: [85, 91]
  • Input: [74, 75, 76, 50, 49, 90]
    Output: [75, 76, 90]
  • Input: [100, 95, 85, 65, 60, 55]
    Output: [100, 95, 85]

Exercise 4: Filter Out Words Starting with 'A'

Task: Create a function to filter out words that start with the letter 'A', regardless of case, from a list of strings.

Example Inputs and Outputs

  • Input: ["Apple", "banana", "Avocado", "grape", "apricot"]
    Output: ["banana", "grape"]
  • Input: ["almond", "Peach", "apricot", "orange", "acorn"]
    Output: ["Peach", "orange"]
  • Input: ["Banana", "apple", "avocado"]
    Output: ["Banana"]
  • Input: ["apron", "antelope", "bison", "ant"]
    Output: ["bison"]

Exercise 5: Filter Specific Character (Case Insensitive)

Task: Filter out all words that do NOT start with the letter 'A', regardless of case, from a list of strings.

Example Inputs and Outputs

  • Input: ["Apple", "banana", "Avocado", "grape", "apricot"]
    Output: ["Apple", "Avocado", "apricot"]
  • Input: ["almond", "Peach", "apricot", "orange", "acorn"]
    Output: ["almond", "apricot", "acorn"]
  • Input: ["Banana", "apple", "avocado"]
    Output: ["apple", "avocado"]
  • Input: ["apron", "antelope", "bison", "ant"]
    Output: ["apron", "antelope", "ant"]

Exercise 6: Filter Adults by Age and Gender

Task: Write a function that filters out all people under 18 years old or whose gender is not specified as female from a list of person records. Each person record should include a name, age, and a gender.

Example Inputs and Outputs

  • Input: [{name = "Alice", age = 25, gender = Female}, {name = "Bob", age = 17, gender = Male}, {name = "Carol", age = 15, gender = Female}]
    Output: [{name = "Alice", age = 25, gender = Female}]
  • Input: [{name = "Dave", age = 30, gender = Male}, {name = "Eve", age = 20, gender = Female}]
    Output: [{name = "Eve", age = 20, gender = Female}]
  • Input: [{name = "Fred", age = 16, gender = Male}, {name = "George", age = 21, gender = Male}, {name = "Helen", age = 19, gender = Female}]
    Output: [{name = "Helen", age = 19, gender = Female}]
  • Input: [{name = "Hannah", age = 14, gender = Female}, {name = "Ian", age = 13, gender = Male}, {name = "Jill", age = 19, gender = Male}]
    Output: []

Exercise 7: Filter Positive Numbers

Task: Remove all non-positive numbers (zero and negatives) from a list of integers.

Example Inputs and Outputs

  • Input: [-10, 0, 5, 20, -30, 0, 40]
    Output: [5, 20, 40]
  • Input: [1, 2, 3, -1, -2, 0]
    Output: [1, 2, 3]
  • Input: [-50, -60, -70]
    Output: []
  • Input: [0, 0, 0, 0, 100]
    Output: [100]

Exercise 8: Filter Multiples of Five

Task: Filter out all numbers that are not multiples of five from a list of integers.

Example Inputs and Outputs

  • Input: [10, 22, 30, 47, 55, 60]
    Output: [10, 30, 55, 60]
  • Input: [5, 11, 15, 23, 25, 40]
    Output: [5, 15, 25, 40]
  • Input: [1, 2, 3, 4, 5, 10, 15]
    Output: [5, 10, 15]
  • Input: [12, 14, 19, 21, 22]
    Output: []

Exercise 9: Filter by Length

Task: Write a function to exclude all elements whose length is not 5 from a list of lists.

Example Inputs and Outputs

  • Input: [[1, 2, 3, 4, 5], [6, 7, 8], [9, 10, 11, 12, 13], [14, 15]]
    Output: [[1, 2, 3, 4, 5], [9, 10, 11, 12, 13]]
  • Input: [[1, 2, 3], [4, 5, 6, 7, 8], [9, 10], [11, 12, 13, 14, 15]]
    Output: [[4, 5, 6, 7, 8], [11, 12, 13, 14, 15]]
  • Input: [[1], [2], [3, 4, 5, 6, 7], [8, 9, 10, 11, 12]]
    Output: [[3, 4, 5, 6, 7], [8, 9, 10, 11, 12]]
  • Input: [[1, 2, 3, 4], [5, 6, 7, 8, 9], [10], [11, 12, 13, 14, 15, 16]]
    Output: [[5, 6, 7, 8, 9]]

Exercise 10: Filter Pending Tasks

Task: From a list of tasks, filter out all tasks that are not marked as pending.

Tasks can be marked as completed, pending, in progress, or under review.

Example Inputs and Outputs

  • Input: [{task = "Email client", status = Completed}, {task = "Update website", status = Pending}, {task = "Call supplier", status = InProgress}, {task = "Prepare report", status = Pending}]
    Output: [{task = "Update website", status = Pending}, {task = "Prepare report", status = Pending}]
  • Input: [{task = "Fix bugs", status = Pending}, {task = "Deploy app", status = Completed}, {task = "Review code", status = Pending}]
    Output: [{task = "Fix bugs", status = Pending}, {task = "Review code", status = Pending}]
  • Input: [{task = "Plan sprint", status = Completed}, {task = "Write tests", status = InProgress}]
    Output: []
  • Input: [{task = "Schedule meeting", status = Pending}, {task = "Update docs", status = Completed}, {task = "Design logo", status = Review}]
    Output: [{task = "Schedule meeting", status = Pending}]

Exercise 11: Filter Valid Emails

Task: Filter out all strings that do not exist in the form <first-part>@<second-part>.<third-part> from a list of potential email addresses.

Example Inputs and Outputs

  • Input: ["alice@example.com", "bob@example", "carol@site.com", "dave@web"]
    Output: ["alice@example.com", "carol@site.com"]
  • Input: ["user@domain.com", "admin@", "@example.com", "info@test.com"]
    Output: ["user@domain.com", "info@test.com"]
  • Input: ["name@company.com", "employee@", "boss@office.com"]
    Output: ["name@company.com", "boss@office.com"]
  • Input: ["@", "support@example.com", "contact@site"]
    Output: ["support@example.com"]

Exercise 12: Filter by Permission

Task: Filter out all users from a list who do not have 'admin' level permissions. Assume each user record includes fields for full name, username, and permission level.

Example Inputs and Outputs

  • Input: [{fullName = "Alice Smith", username = "alice", permission = Admin}, {fullName = "Bob Johnson", username = "bob", permission = User}, {fullName = "Carol White", username = "carol", permission = Admin}]
    Output: [{fullName = "Alice Smith", username = "alice", permission = Admin}, {fullName = "Carol White", username = "carol", permission = Admin}]
  • Input: [{fullName = "Dave Brown", username = "dave", permission = User}, {fullName = "Eve Black", username = "eve", permission = Admin}, {fullName = "Frank Ray", username = "frank", permission = Guest}]
    Output: [{fullName = "Eve Black", username = "eve", permission = Admin}]
  • Input: [{fullName = "Grace Lee", username = "grace", permission = User}, {fullName = "Helen Green", username = "helen", permission = User}]
    Output: []
  • Input: [{fullName = "Ian Grey", username = "ian", permission = Admin}, {fullName = "Jill Gold", username = "jill", permission = Admin}, {fullName = "Kelly Fox", username = "kelly", permission = User}]
    Output: [{fullName = "Ian Grey", username = "ian", permission = Admin}, {fullName = "Jill Gold", username = "jill", permission = Admin}]

Exercise 13: Filter Products by Price

Task: Remove all products from a list that are priced above $5.00. Assume each product record includes fields for product name, category, and price.

Example Inputs and Outputs

  • Input: [{productName = "Milk", category = "Dairy", price = 4.99}, {productName = "Cheese", category = "Dairy", price = 6.50}, {productName = "Butter", category = "Dairy", price = 5.49}]
    Output: [{productName = "Milk", category = "Dairy", price = 4.99}]
  • Input: [{productName = "Bread", category = "Bakery", price = 3.49}, {productName = "Cake", category = "Bakery", price = 7.99}]
    Output: [{productName = "Bread", category = "Bakery", price = 3.49}]
  • Input: [{productName = "Yogurt", category = "Dairy", price = 0.99}, {productName = "Ice cream", category = "Frozen", price = 5.99}]
    Output: [{productName = "Yogurt", category = "Dairy", price = 0.99}]
  • Input: [{productName = "Pasta", category = "Grocery", price = 2.50}, {productName = "Olive oil", category = "Grocery", price = 10.99}]
    Output: [{productName = "Pasta", category = "Grocery", price = 2.50}]

Exercise 14: Filter Products by Converted Prices

Task: Remove all products from a list whose price, when converted to U.S. dollars, is above $5.00. Each product record includes a price that is a record with fields for amount and currency. Use the provided conversion rates to convert prices to U.S. dollars before filtering.

Conversion Rates:

  • EUR to USD: 1.18
  • GBP to USD: 1.31
  • CAD to USD: 0.79

Example Inputs and Outputs

  • Input: [{productName = "Milk", category = "Dairy", price = {amount = 4.00, currency = USD}}, {productName = "Cheese", category = "Dairy", price = {amount = 5.00, currency = EUR}}]
    Output: [{productName = "Milk", category = "Dairy", price = {amount = 4.00, currency = USD}}]
  • Input: [{productName = "Bread", category = "Bakery", price = {amount = 3.00, currency = USD}}, {productName = "Butter", category = "Dairy", price = {amount = 6.00, currency = GBP}}]
    Output: [{productName = "Bread", category = "Bakery", price = {amount = 3.00, currency = USD}}]
  • Input: [{productName = "Yogurt", category = "Dairy", price = {amount = 6.50, currency = CAD}}, {productName = "Ice cream", category = "Frozen", price = {amount = 5.50, currency = CAD}}]
    Output: []
  • Input: [{productName = "Pasta", category = "Grocery", price = {amount = 4.50, currency = USD}}, {productName = "Olive oil", category = "Grocery", price = {amount = 7.00, currency = EUR}}]
    Output: [{productName = "Pasta", category = "Grocery", price = {amount = 4.50, currency = USD}}]

Exercise 15: Filter Animals by Habitat

Task: Filter out all animals that do not live in aquatic habitat from a list. Assume each animal record includes fields for name, species, and habitat.

Context: The possible habitats for animals are as follows:

  • Aquatic: For animals living primarily in water, like sharks and whales.
  • Terrestrial: For land-dwelling animals, such as bears and rabbits.
  • Arboreal: For animals that live in trees, like tree frogs.

Example Inputs and Outputs

  • Input: [{name = "Shark", species = "Great White Shark", habitat = Aquatic}, {name = "Eagle", species = "Bald Eagle", habitat = Terrestrial}]
    Output: [{name = "Shark", species = "Great White Shark", habitat = Aquatic}]
  • Input: [{name = "Dolphin", species = "Bottlenose Dolphin", habitat = Aquatic}, {name = "Bear", species = "Grizzly Bear", habitat = Terrestrial}]
    Output: [{name = "Dolphin", species = "Bottlenose Dolphin", habitat = Aquatic}]
  • Input: [{name = "Whale", species = "Blue Whale", habitat = Aquatic}, {name = "Frog", species = "Tree Frog", habitat = Arboreal}]
    Output: [{name = "Whale", species = "Blue Whale", habitat = Aquatic}]
  • Input: [{name = "Otter", species = "Sea Otter", habitat = Aquatic}, {name = "Rabbit", species = "Cottontail Rabbit", habitat = Terrestrial}]
    Output: [{name = "Otter", species = "Sea Otter", habitat = Aquatic}]

Exercise 16: Filter by Tag

Task: Exclude all items from a list that do not have a specific tag attached. Assume each item record includes fields for item name, price, and a list of tags. Your function should be able to filter by just any tag that's passed to it as argument.

Example Inputs and Outputs

For example, if we're filtering by the tag 'Portable':

  • Input: [{itemName = "Laptop", price = 1200, tags = [Electronics, Portable]}, {itemName = "Desk", price = 450, tags = [Furniture]}]
    Output: [{itemName = "Laptop", price = 1200, tags = [Electronics, Portable]}]
  • Input: [{itemName = "Smartphone", price = 999, tags = [Electronics, Mobile, Portable]}, {itemName = "Chair", price = 150, tags = [Furniture]}]
    Output: [{itemName = "Smartphone", price = 999, tags = [Electronics, Mobile, Portable]}]
  • Input: [{itemName = "Backpack", price = 70, tags = [Portable, Travel]}, {itemName = "Sofa", price = 1200, tags = [Furniture, Comfort]}]
    Output: [{itemName = "Backpack", price = 70, tags = [Portable, Travel]}]
  • Input: [{itemName = "Tablet", price = 600, tags = [Electronics, Portable]}, {itemName = "Bookcase", price = 320, tags = [Furniture]}]
    Output: [{itemName = "Tablet", price = 600, tags = [Electronics, Portable]}]

PREV: Map it like it's hot!
NEXT:

@Ikechukwunwachukwu
Copy link

Nice, nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment