$30 off During Our Annual Pro Sale. View Details »

Functional Programming in Dart - A practical approach

Functional Programming in Dart - A practical approach

Functional programming has been a recent trend in the market and has many things to offer for increasing developer productivity. We're going to cover what Functional APIs are available in Dart and how they can help us write clear and concise code.

Spearkers: Samvid Mistry & Tirth Patel

Tirth Patel

April 13, 2019
Tweet

Other Decks in Programming

Transcript

  1. Functional Programming
    in Dart
    A practical approach

    View Slide

  2. Course of talk
    • Functions & Variables
    • First class & Higher order functions
    • Lambdas
    • Code quality and quantity
    • List APIs

    View Slide

  3. Functions & Variables

    View Slide

  4. Properties of functions
    • Purity
    • Only depends on data provided to it
    • add(a, b) => a + b; //Pure
    • int a;

    add(b) => a + b; //Impure

    View Slide

  5. Properties of functions
    • Referential transparency
    • A function always returns the same value on same input,
    no matter when you call it
    • add(a,b) => a + b; //transparent
    • int a;

    add(b) => a + b; //not transparent
    • a = 5, add(5) => 10; a = 10, add(5) => 15
    • Facilitated by purity of functions

    View Slide

  6. Properties of variables
    • Immutable, final, const.
    • Functional Programming principles are language
    independent
    • All math functions are referentially transparent, i.e.
    Math.sin(s), Math.sqrt(x), Math.max(a,b).

    View Slide

  7. Why, bruh?
    • Why should variables be immutable?
    • No race conditions.
    • Less cognitive load.
    • Why should functions be pure?
    • Concurrency and parallel evaluation.
    • Why should functions be referentially transparent?
    • Lazy evaluation.

    View Slide

  8. First class & Higher
    order functions

    View Slide

  9. First class functions
    • What does it mean to be first class?
    • First class = type system can make sense of it.
    • Imperative: a = 5; a = "string"; a = new Object();
    • Functional: var f = (a) => (a + 1)
    • Type: (int) -> int
    • In general: (parameter_types) -> return_type

    View Slide

  10. Higher order functions
    • Simply put, it is a function which takes function as
    argument and/or returns a function.
    • apply(Function f, int a) { return f(a); }
    • Function createAdder(int a) { return (b) => a + b; }
    • Function chaining: createAdder(10)(20)

    View Slide

  11. Lambdas

    View Slide

  12. Lambdas
    • OOP => Inheritance, top-down approach
    • Functional => composition, bottom-up approach
    • Naming is one of the biggest problems in programming
    • Lambda = anonymous function
    • (param1, param2, ...) => single_statement
    • (param1, param2, ...) { //multiple statements }
    • var adder = (a, b) => a + b;

    View Slide

  13. Code quality and
    quantity

    View Slide

  14. Code quality and quantity
    • Functional APIs help you write less code
    • Not laziness, but conciseness
    • More code = More chances of error
    • APIs = tried, tested and stable code
    • "Best code is no code at all" - Unknown
    • "We use code like violence. if it doesn't work, we use
    more of it" - Venkat Subramaniam

    View Slide

  15. –Albert Einstein
    “e = (mc) ”
    2

    View Slide

  16. –Albert Einstein
    “errors = (more code) ”
    2

    View Slide

  17. FP APIs for Iterable

    View Slide

  18. removeWhere
    List list = List.generate(10, (i) => i);
    for (int i in list) {
    if (i % 2 == 0)
    list.remove(i);
    }

    View Slide

  19. removeWhere
    List list = List.generate(10, (i) => i);
    for (int i in list) {
    if (i % 2 == 0)
    list.remove(i);
    }

    View Slide

  20. removeWhere
    List list = List.generate(10, (i) => i);
    for (int i in list) {
    if (i % 2 == 0)
    list.remove(i);
    }

    View Slide

  21. removeWhere
    List list = List.generate(10, (i) => i);
    for (int i in list) {
    if (i % 2 == 0)
    list.remove(i);
    }

    View Slide

  22. removeWhere
    List list = List.generate(10, (i) => i);
    for (int i in list) {
    if (i % 2 == 0)
    list.remove(i);
    }

    View Slide

  23. removeWhere
    List list = List.generate(10, (i) => i);


    list.removeWhere((f) => f % 2 == 0);

    View Slide

  24. any
    List list = List.generate(10, (i) => i);
    bool isFound = false;
    for (int i in list) {
    if (i % 2 == 0) {
    isFound = true;
    break;
    }
    }
    if (isFound) print("Found");

    View Slide

  25. any
    List list = List.generate(10, (i) => i);
    bool isFound = false;
    for (int i in list) {
    if (i % 2 == 0) {
    isFound = true;
    break;
    }
    }
    if (isFound) print("Found");

    View Slide

  26. any
    List list = List.generate(10, (i) => i);
    bool isFound = false;
    for (int i in list) {
    if (i % 2 == 0) {
    isFound = true;
    break;
    }
    }
    if (isFound) print("Found");

    View Slide

  27. any
    List list = List.generate(10, (i) => i);
    bool isFound = false;
    for (int i in list) {
    if (i % 2 == 0) {
    isFound = true;
    break;
    }
    }
    if (isFound) print("Found");

    View Slide

  28. any
    List list = List.generate(10, (i) => i);
    bool isFound = false;
    for (int i in list) {
    if (i % 2 == 0) {
    isFound = true;
    break;
    }
    }
    if (isFound) print("Found");

    View Slide

  29. any
    List list = List.generate(10, (i) => i);
    bool isFound = false;
    for (int i in list) {
    if (i % 2 == 0) {
    isFound = true;
    break;
    }
    }
    if (isFound) print("Found");

    View Slide

  30. any
    List list = List.generate(10, (i) => i);
    list.any((i) => i % 2 == 0) ? print("Found") : print(“Not Found”);

    View Slide

  31. firstWhere
    List list = List.generate(10, (i) => i);
    int index = -1;
    for (int i in list) {
    if (i % 2 == 0) {
    index = i;
    break;
    }
    }
    if (index != -1) print("Found ${list[index].toString()}");

    View Slide

  32. firstWhere
    List list = List.generate(10, (i) => i);
    int index = -1;
    for (int i in list) {
    if (i % 2 == 0) {
    index = i;
    break;
    }
    }
    if (index != -1) print("Found ${list[index].toString()}");

    View Slide

  33. firstWhere
    List list = List.generate(10, (i) => i);
    int index = -1;
    for (int i in list) {
    if (i % 2 == 0) {
    index = i;
    break;
    }
    }
    if (index != -1) print("Found ${list[index].toString()}");

    View Slide

  34. firstWhere
    List list = List.generate(10, (i) => i);
    int index = -1;
    for (int i in list) {
    if (i % 2 == 0) {
    index = i;
    break;
    }
    }
    if (index != -1) print("Found ${list[index].toString()}");

    View Slide

  35. firstWhere
    List list = List.generate(10, (i) => i);
    int index = -1;
    for (int i in list) {
    if (i % 2 == 0) {
    index = i;
    break;
    }
    }
    if (index != -1) print("Found ${list[index].toString()}");

    View Slide

  36. firstWhere
    List list = List.generate(10, (i) => i);
    int index = -1;
    for (int i in list) {
    if (i % 2 == 0) {
    index = i;
    break;
    }
    }
    if (index != -1) print("Found ${list[index].toString()}");

    View Slide

  37. firstWhere
    List list = List.generate(10, (i) => i);
    int element = list.firstWhere((i) => i % 2 == 0, orElse: () => -1);
    if(element != -1) {
    print("Found $element");
    }

    View Slide

  38. every
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    bool isAllA = true;
    for (String follower in followers) {
    if (!(follower.startsWith("a"))) isAllA = false;
    }
    if (isAllA) print("Good to go");
    else print("Uh oh");

    View Slide

  39. every
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    bool isAllA = true;
    for (String follower in followers) {
    if (!(follower.startsWith("a"))) isAllA = false;
    }
    if (isAllA) print("Good to go");
    else print("Uh oh");

    View Slide

  40. every
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    bool isAllA = true;
    for (String follower in followers) {
    if (!(follower.startsWith("a"))) isAllA = false;
    }
    if (isAllA) print("Good to go");
    else print("Uh oh");

    View Slide

  41. every
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    bool isAllA = true;
    for (String follower in followers) {
    if (!(follower.startsWith("a"))) isAllA = false;
    }
    if (isAllA) print("Good to go");
    else print("Uh oh");

    View Slide

  42. every
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    bool isAllA = true;
    for (String follower in followers) {
    if (!(follower.startsWith("a"))) isAllA = false;
    }
    if (isAllA) print("Good to go");
    else print("Uh oh");

    View Slide

  43. every
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    bool isAllA = true;
    for (String follower in followers) {
    if (!(follower.startsWith("a"))) isAllA = false;
    }
    if (isAllA) print("Good to go");
    else print("Uh oh");

    View Slide

  44. every
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    if(followers.every((s) => s.startsWith("a")))
    print("Good to go");
    else
    print("Uh oh");

    View Slide

  45. join
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    StringBuffer buffer = StringBuffer();
    for (int i = 0; i < followers.length; i++) {
    if (i == followers.length - 1) buffer.write(followers[i]);
    else buffer.write(followers[i] + ", ");
    }
    print(buffer.toString());

    View Slide

  46. join
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    StringBuffer buffer = StringBuffer();
    for (int i = 0; i < followers.length; i++) {
    if (i == followers.length - 1) buffer.write(followers[i]);
    else buffer.write(followers[i] + ", ");
    }
    print(buffer.toString());

    View Slide

  47. join
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    StringBuffer buffer = StringBuffer();
    for (int i = 0; i < followers.length; i++) {
    if (i == followers.length - 1) buffer.write(followers[i]);
    else buffer.write(followers[i] + ", ");
    }
    print(buffer.toString());

    View Slide

  48. join
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    StringBuffer buffer = StringBuffer();
    for (int i = 0; i < followers.length; i++) {
    if (i == followers.length - 1) buffer.write(followers[i]);
    else buffer.write(followers[i] + ", ");
    }
    print(buffer.toString());

    View Slide

  49. join
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    StringBuffer buffer = StringBuffer();
    for (int i = 0; i < followers.length; i++) {
    if (i == followers.length - 1) buffer.write(followers[i]);
    else buffer.write(followers[i] + ", ");
    }
    print(buffer.toString());

    View Slide

  50. join
    List followers =
    List.generate(10, (i) => "a".padLeft((i % 2) * 5, "z"));
    StringBuffer buffer = StringBuffer();
    for (int i = 0; i < followers.length; i++) {
    if (i == followers.length - 1) buffer.write(followers[i]);
    else buffer.write(followers[i] + ", ");
    }
    print(buffer.toString());

    View Slide

  51. join
    List followers =
    List.generate(10, (i) => "a".padLeft((i %
    2) * 5, "z")
    print(followers.join(", "));

    View Slide

  52. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    double sum = 0;
    for (Employee e in employees) {
    sum += e.salary;
    }
    return sum / employees.length;
    }

    View Slide

  53. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    double sum = 0;
    for (Employee e in employees) {
    sum += e.salary;
    }
    return sum / employees.length;
    }

    View Slide

  54. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    double sum = 0;
    for (Employee e in employees) {
    sum += e.salary;
    }
    return sum / employees.length;
    }

    View Slide

  55. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    double sum = 0;
    for (Employee e in employees) {
    sum += e.salary;
    }
    return sum / employees.length;
    }

    View Slide

  56. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    double sum = 0;
    for (Employee e in employees) {
    sum += e.salary;
    }
    return sum / employees.length;
    }

    View Slide

  57. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    double sum = 0;
    for (Employee e in employees) {
    sum += e.salary;
    }
    return sum / employees.length;
    }

    View Slide

  58. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    double sum = 0;
    for (Employee e in employees) {
    sum += e.salary;
    }
    return sum / employees.length;
    }

    View Slide

  59. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    return employees.fold(0, (s, e) => s + e.salary) / employees.length;
    }

    View Slide

  60. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    return employees.fold(0, (s, e) => s + e.salary) / employees.length;
    }

    View Slide

  61. fold
    List employees = List.generate(
    10, (i) => new Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(averageSalary(employees));
    double averageSalary(List employees) {
    return employees.fold(0, (s, e) => s + e.salary) / employees.length;
    }

    View Slide

  62. employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: a
    salary: 0
    }
    Employee {
    name: az
    salary: 1000
    }
    Employee {
    name: azz
    salary: 2000
    }
    0

    View Slide

  63. employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: a
    salary: 0
    }
    Employee {
    name: az
    salary: 1000
    }
    Employee {
    name: azz
    salary: 2000
    }
    0

    View Slide

  64. employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: a
    salary: 0
    }
    Employee {
    name: az
    salary: 1000
    }
    Employee {
    name: azz
    salary: 2000
    }
    0

    View Slide

  65. employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: a
    salary: 0
    }
    Employee {
    name: az
    salary: 1000
    }
    Employee {
    name: azz
    salary: 2000
    }
    0

    View Slide

  66. employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: az
    salary: 1000
    }
    Employee {
    name: azz
    salary: 2000
    }
    Employee {
    name: azzz
    salary: 30
    }
    0

    View Slide

  67. employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: az
    salary: 1000
    }
    Employee {
    name: azz
    salary: 2000
    }
    Employee {
    name: azzz
    salary: 30
    }
    0

    View Slide

  68. 1000
    employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: az
    salary: 1000
    }
    Employee {
    name: azz
    salary: 2000
    }
    Employee {
    name: azzz
    salary: 30
    }

    View Slide

  69. 1000
    employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: azz
    salary: 2000
    }
    Employee {
    name: azzz
    salary: 3000
    }
    Employee {
    name: azzz
    salary: 40
    }

    View Slide

  70. 1000
    employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: azz
    salary: 2000
    }
    Employee {
    name: azzz
    salary: 3000
    }
    Employee {
    name: azzz
    salary: 40
    }

    View Slide

  71. 3000
    employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: azz
    salary: 2000
    }
    Employee {
    name: azzz
    salary: 3000
    }
    Employee {
    name: azzz
    salary: 40
    }

    View Slide

  72. 3000
    employees.fold(0, (s, e) => s + e.salary)
    Employee {
    name: azzz
    salary: 3000
    }
    Employee {
    name: azzzz
    salary: 4000
    }
    Employee {
    name: azzz
    salary: 50
    }

    View Slide

  73. Fold as (almost) universal function
    • employees.max()

    employees.fold(0, (s, e) => (e.salary > s) ? e.salary : s)
    • employees.any(predicate)

    employees.fold(false, (s, e) => 

    (s == false) ? predicate(e) : true)
    • employees.every(predicate)

    employees.fold(true, (s, e) =>

    (s == true) ? predicate(e) : false)

    View Slide

  74. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    List names = List();
    for (Employee e in employees) {
    names.add(e.name.replaceRange(0, 1, e.name[0].toUpperCase()));
    }
    return names;
    }

    View Slide

  75. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    List names = List();
    for (Employee e in employees) {
    names.add(e.name.replaceRange(0, 1, e.name[0].toUpperCase()));
    }
    return names;
    }

    View Slide

  76. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    List names = List();
    for (Employee e in employees) {
    names.add(e.name.replaceRange(0, 1, e.name[0].toUpperCase()));
    }
    return names;
    }

    View Slide

  77. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    List names = List();
    for (Employee e in employees) {
    names.add(e.name.replaceRange(0, 1, e.name[0].toUpperCase()));
    }
    return names;
    }

    View Slide

  78. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    List names = List();
    for (Employee e in employees) {
    names.add(e.name.replaceRange(0, 1, e.name[0].toUpperCase()));
    }
    return names;
    }

    View Slide

  79. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    List names = List();
    for (Employee e in employees) {
    names.add(e.name.replaceRange(0, 1, e.name[0].toUpperCase()));
    }
    return names;
    }

    View Slide

  80. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    List names = List();
    for (Employee e in employees) {
    names.add(e.name.replaceRange(0, 1, e.name[0].toUpperCase()));
    }
    return names;
    }

    View Slide

  81. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    List names = List();
    for (Employee e in employees) {
    names.add(e.name.replaceRange(0, 1, e.name[0].toUpperCase()));
    }
    return names;
    }

    View Slide

  82. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    List names = List();
    for (Employee e in employees) {
    names.add(e.name.replaceRange(0, 1, e.name[0].toUpperCase()));
    }
    return names;
    }

    View Slide

  83. map
    List employees =
    List.generate(10, (i) => Employee("a".padRight(i + 1, "z"), i * 1000));
    employees.shuffle();
    print(capitalize(employees));
    List capitalize(List employees) {
    return employees
    .map((e) => e.name.replaceRange(0, 1, e.name[0].toUpperCase())).toList();
    }

    View Slide

  84. where
    List numbers = List.generate(10, (i) => i);
    for (int number in numbers) {
    if (number % 2 == 1) {
    print("$number is odd");
    }
    }
    for (int number in numbers) {
    if (number % 2 == 0) {
    print("$number is even");
    }
    }

    View Slide

  85. where
    List numbers = List.generate(10, (i) => i);
    for (int number in numbers) {
    if (number % 2 == 1) {
    print("$number is odd");
    }
    }
    for (int number in numbers) {
    if (number % 2 == 0) {
    print("$number is even");
    }
    }

    View Slide

  86. where
    List numbers = List.generate(10, (i) => i);
    for (int number in numbers) {
    if (number % 2 == 1) {
    print("$number is odd");
    }
    }
    for (int number in numbers) {
    if (number % 2 == 0) {
    print("$number is even");
    }
    }

    View Slide

  87. where
    List numbers = List.generate(10, (i) => i);
    for (int number in numbers) {
    if (number % 2 == 1) {
    print("$number is odd");
    }
    }
    for (int number in numbers) {
    if (number % 2 == 0) {
    print("$number is even");
    }
    }

    View Slide

  88. where
    List numbers = List.generate(10, (i) => i);
    for (int number in numbers) {
    if (number % 2 == 1) {
    print("$number is odd");
    }
    }
    for (int number in numbers) {
    if (number % 2 == 0) {
    print("$number is even");
    }
    }

    View Slide

  89. where
    List numbers = List.generate(10, (i) => i);
    for (int number in numbers) {
    if (number % 2 == 1) {
    print("$number is odd");
    }
    }
    for (int number in numbers) {
    if (number % 2 == 0) {
    print("$number is even");
    }
    }

    View Slide

  90. where
    List numbers = List.generate(10, (i) => i);
    for (int number in numbers) {
    if (number % 2 == 1) {
    print("$number is odd");
    }
    }
    for (int number in numbers) {
    if (number % 2 == 0) {
    print("$number is even");
    }
    }

    View Slide

  91. where
    List numbers = List.generate(10, (i) => i);
    for (int number in numbers) {
    if (number % 2 == 1) {
    print("$number is odd");
    }
    }
    for (int number in numbers) {
    if (number % 2 == 0) {
    print("$number is even");
    }
    }

    View Slide

  92. where
    List numbers = List.generate(10, (i) => i);
    numbers
    .where((number) => number % 2 == 1)
    .forEach((number) => print("$number is odd"));
    numbers
    .where((number) => number % 2 == 0)
    .forEach((number) => print("$number is even"));

    View Slide

  93. More Functional APIs
    • https://api.dartlang.org/stable/2.2.0/dart-
    core/Iterable-class.html#instance-methods
    • https://api.dartlang.org/stable/2.2.0/dart-
    async/Stream-class.html#instance-methods

    View Slide

  94. A Combined Example

    View Slide

  95. words.txt
    art
    bread
    dartisan
    mart
    data
    dartium
    earth
    datamart
    eggs
    state of the art dart
    spinach
    dart
    rider
    part

    View Slide

  96. main.dart
    File('words.txt')
    .readAsStringSync()
    .split('\n')
    .where((word) => word.contains('dart'))
    .map((word) => '${String.fromCharCodes(Runes('\u2764'))} -> $word')
    .forEach((word) => print(word));

    View Slide

  97. main.dart
    File('words.txt')
    .readAsStringSync()
    .split('\n')
    .where((word) => word.contains('dart'))
    .map((word) => '${String.fromCharCodes(Runes('\u2764'))} -> $word')
    .forEach((word) => print(word));

    View Slide

  98. main.dart
    File('words.txt')
    .readAsStringSync()
    .split('\n')
    .where((word) => word.contains('dart'))
    .map((word) => '${String.fromCharCodes(Runes('\u2764'))} -> $word')
    .forEach((word) => print(word));

    View Slide

  99. main.dart
    File('words.txt')
    .readAsStringSync()
    .split('\n')
    .where((word) => word.contains('dart'))
    .map((word) => '${String.fromCharCodes(Runes('\u2764'))} -> $word')
    .forEach((word) => print(word));

    View Slide

  100. main.dart
    File('words.txt')
    .readAsStringSync()
    .split('\n')
    .where((word) => word.contains('dart'))
    .map((word) => '${String.fromCharCodes(Runes('\u2764'))} -> $word')
    .forEach((word) => print(word));

    View Slide

  101. main.dart
    File('words.txt')
    .readAsStringSync()
    .split('\n')
    .where((word) => word.contains('dart'))
    .map((word) => '${String.fromCharCodes(Runes('\u2764'))} -> $word')
    .forEach((word) => print(word));

    View Slide

  102. Output
    ❤ -> dartisan
    ❤ -> dartium
    ❤ -> state of the art dart
    ❤ -> dart

    View Slide

  103. Thank You!
    Questions?

    View Slide

  104. • github.com/samvidmistry
    • github.com/piedcipher
    • twitter.com/@mistrysamvid
    • twitter.com/@piedcipher
    • medium.com/@samvidmistry
    • medium.com/@piedcipher

    View Slide