상세 컨텐츠

본문 제목

Dart - data collection

Dart

by techbard 2023. 12. 5. 17:41

본문

반응형
void main(List<String> args) {

const items = [1, 2, 3, 4, 5];

for (int i in items) {
  if (i % 2 == 0) {
    print("[01] 숫자 $i는 짝수");
  }
}
print('--------------------------------------------------');

items.where((element) => element % 2 == 0).map((e) => "[02] 숫자 $e는 짝수").forEach(print);
}

// 결과

[01] 숫자 2는 짝수
[01] 숫자 4는 짝수
--------------------------------------------------
[02] 숫자 2는 짝수
[02] 숫자 4는 짝수

 

void main(List<String> args) {
  // Dart에서 대부분의 함수는 Iterable<T>로 분류되는 인터페이스 타입의 인스턴스를 반환
  // 실 사용에서 이것을 리스트로 변환해야 하는 경우가 많음
  // toList() 함수는 where(), map() 과 같은 Iterable 인터페이스를 반환하는 메서드에서 사용 가능
  
  const items = [1, 2, 3, 4, 5];
  final result = items.map((element) => element + 1).toList();
  print("list element + 1 is $result");

  final sumResult = items.reduce((value, element) => value + element);
  print("sum of items is $sumResult");
}

// 결과
list element + 1 is [2, 3, 4, 5, 6]
sum of items is 15

 

// list syntax

void main() {
  List<int> li = [1, 2, 3];

  print("[1] list length is ${li.length}");
  print("[2] list item is $li");

  for (int i=0; i<li.length; i++) {
    li[i] += 1;
  }
  print("[3] after plus, list item is $li");

  List<int> neoli = [...?li, 5, 6];
  print("[4] new list is $neoli");

  neoli.clear();
  print("[5] new list cleared: $neoli");
  neoli = [if(li.isNotEmpty) ...li, 5, 6];
  print("[6] another new list is $neoli");

  for (int i in neoli) {
    print("[7]>> $i");
  }
}

// 결과
[1] list length is 3
[2] list item is [1, 2, 3]
[3] after plus, list item is [2, 3, 4]
[4] new list is [2, 3, 4, 5, 6]
[5] new list cleared: []
[6] another new list is [2, 3, 4, 5, 6]
[7]>> 2
[7]>> 3
[7]>> 4
[7]>> 5
[7]>> 6

 

void main(List<String> args) {
  // 계단식 표기법(cascade notation)
  //
  // ..연산자 사용하면 같은 객체에 대해 연속적인 작업 수행 가능
  // remove() 메서드는 bool을 반환하고 toSet() 함수는 Set<T>를 반환하지만
  // ..연산자를 사용하면 호출한 객체의 참조를 반환한다.
  // 매번 result 리스트를 반환해서 임시 변수를 만드는 단계를 생략하고 직관적인 코드 생성

  const rawList = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  var result = [];
  result = [for (int i in rawList) if (i % 2 == 0) i]; // 짝수만 담은 리스트 반환
  result
  ..remove(result.length) // 마지막 요소 삭제
  ..toSet(); // 중복 요소 삭제

  print("[01] in: $rawList");
  print("[02] result: $result");
}

// 결과
[01] in: [1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[02] result: [2, 4, 6, 8, 10]

 

// Using the map() with the where() method

void main(List<String> args) {
  var inData01 = [1, 2, 3, 'a'];
  // 숫자만 추출
  var nums01 = inData01.where((e) => e.runtimeType == int);
  print(nums01);

  var inData02 = ['1.1', '2.2', 'abc'];

  // 문자열이지만 double로 파싱 가능한 것만 필터링
  var nums02 = inData02.map((e) => double.tryParse(e)).where((n) => n != null);
  print(nums02);
}

// 결과
(1, 2, 3)
(1.1, 2.2)

 

// Collection-for

void main(List<String> args) {
  const addBlue = false;
  const addRed = true;
  const extraColors = ['yellow', 'green'];
  final colors = [
    'gray',
    'brown',
    if (addBlue) 'blue',
    if (addRed) 'red',
    for (var color in extraColors) color
  ];

  // or
  // colors.addAll(extraColors);

  print(colors);
}

// 결과
[gray, brown, red, yellow, green]

 

void main(List<String> args) {
  final originalList = [1, 2, 3];
  // only the reference is copied, not the actual values.
  final copyList = originalList;
  copyList[0] = 0;

  print("originalList: $originalList");
  print("copyList: $copyList");

  print("");
  // actual copy #1
  final anotherOriginalList = [1, 2, 3];
  final actualCopyList01 = [for (var item in anotherOriginalList) item];
  print(actualCopyList01);

  // actual copy #2
  final actualCopyList02 = [...anotherOriginalList]; // copy all values
  print(actualCopyList02);
}

// 결과
originalList: [0, 2, 3]
copyList: [0, 2, 3]

[1, 2, 3]
[1, 2, 3]

 

void main(List<String> args) {
  const list = [1, 2, 3, 4];

  final even = list.where((element) => element % 2 == 0);
  print(even);

  final five = list.firstWhere((x) => x == 5, orElse: () => -1);
  print(five);
}

/*
Summary:
  Use where and firstWhere to filter and find items inside a collection
*/

// 결과
(2, 4)
-1

 

// Implement the 'where' function

void main(List<String> args) {
  const list = [1, 2, 3, 4];
  final odd = where<int>(list, (value) => value % 2 == 1);
  print(odd);
}

List<T> where<T>(List<T> items, bool Function(T) f) {
  var results = <T>[];

  for (var item in items) {
    if (f(item)) {
      results.add(item);
    }
  }
  return results;
}

// 결과
[1, 3]

 

// Implement the 'firstWhere' function

void main(List<String> args) {
  const list = [1, 2, 3, 4];
  final result = firstWhere(list, (x) => x == 5, orElse: () => -1);
  print(result);
}

T firstWhere<T>(List<T> items, bool Function(T) f,
    {required T Function() orElse}) {
  for (var item in items) {
    if (f(item)) {
      return item;
    }
  }
  return orElse();
}

// 결과
-1

 

/*
Functional or Imperative programming?

  - It depends
  - Choose the style that makes your code easier to read
  on a case by case basis
  - Functional style works great when manipulating collections
*/

void main(List<String> args) {
  const emails = [
    'abc@abc.com',
    'me@example.co.uk',
    'john@gmail.com',
    'katy@yahoo.com',
  ];

  const knownDomains = ['gmail.com', 'yahoo.com'];

  // Iterables support functional operators
  // This is a functional style logic,
  // but can make code easier to write and read
  final UnknownDomains = emails
      .map((e) => e.split('@').last)
      .where((domain) => !knownDomains.contains(domain));

  print(UnknownDomains);
  print('');
  print(getUnknownDomains(emails, knownDomains));
}

// Imperative style
// (Sequence of steps + control flow statements)
Iterable<String> getUnknownDomains(
    List<String> emails, List<String> knownDomains) {
  var results = <String>[];

  for (var email in emails) {
    final domain = email.split('@').last;
    if (!knownDomains.contains(domain)) {
      results.add(domain);
    }
  }
  return results;
}

// 결과
[abc.com, example.co.uk]

 

import 'dart:math' as Math;

void main(List<String> args) {
  var nums = Iterable.generate(10);
  print(nums.toList());

  var nums2 = Iterable.generate(5, (index) => index + 1);
  print(nums2);

  var numsList = [];
  nums2.forEach((n) => numsList.add(n));
  print(numsList);

  print(nums2.takeWhile((value) => value < 3));
  // the false is returned, iterable stops (!)

  print('sum = ${nums2.reduce((prev, next) => prev + next)}');

  print('(1, 2) min is ${Math.min(1, 2)}');
  print('(1, 2) max is ${Math.max(1, 2)}');

  print('math min: ${nums2.reduce((Math.min))}');
  print('math max: ${nums2.reduce((Math.max))}');
  // https://stackoverflow.com/questions/63377133/how-to-find-the-min-and-max-values-from-a-list-in-dart

  Map<int, int> nums2Map =
      Map.fromIterable(nums2.takeWhile((value) => value < 3));
  print(nums2Map);

  var newMap = nums2Map.map((key, value) => MapEntry(key, key + value));
  print(newMap);
}

// 결과
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
(1, 2, 3, 4, 5)
[1, 2, 3, 4, 5]
(1, 2)
sum = 15
(1, 2) min is 1
(1, 2) max is 2
math min: 1
math max: 5
{1: 1, 2: 2}
{1: 2, 2: 4}

 

void main(List<String> args) {
  var adminOther = [
    'john@gmail.com',
    'sam@gmail.com',
  ];

  var someMoreAdmin = [
    'jake@gmail.com',
    'angela@gmail.com',
  ];

  var user = {
    'username': 'johan@gmail.com',
    'admin': false,
  };

  var admin = [
    'peter@gmail.com',
    'paul@gmail.com',
    'lee@gmail.com',
    if (user['admin'] as bool) user['username'],
    for (var other in adminOther) other,
    ...someMoreAdmin,
  ];

  print(admin);

  // copying collection

  var collection1 = [1, 2, 3];
  var collection2 = collection1;

  collection1[0] = 0;

  print('');

  // point out to same collection
  print('collection1: $collection1');
  print('collection2: $collection2');

  print('');

  var collection3 = [1, 2, 3];
  var collection4 = [...collection3];

  collection3[0] = 0;

  // seperate collection
  print('collection3: $collection3');
  print('collection4: $collection4');
}



 /*
collection if
collection for
spreads
copy collections
 */

// 결과
[peter@gmail.com, paul@gmail.com, lee@gmail.com, john@gmail.com, sam@gmail.com, jake@gmail.com, angela@gmail.com]
collection1: [0, 2, 3]
collection2: [0, 2, 3]

collection3: [0, 2, 3]
collection4: [1, 2, 3]

 

void main(List<String> args) {
  final l = [1, 2, 3, 4, 5];

  // transformer
  // return to new list
  var newL = l.map((e) => e + 1);

  print(newL.toList());

  print('');

  final String number = '134579';

  final parsed = number.split('').map((e) => '$e.jpg').toList();

  print(parsed);
}

// 결과
[2, 3, 4, 5, 6]

[1.jpg, 3.jpg, 4.jpg, 5.jpg, 7.jpg, 9.jpg]

 

void main(List<String> args) {
  Map<String, String> nums = {
    '1': '하나',
    '2': '둘',
    '3': '셋',
  };

  final result = nums.map((key, value) => MapEntry('[$key]', '[$value]'));
  print(result);

  print('');

  var newList = [];

  for (var m in nums.entries) {
    newList.add('${m.key} - ${m.value}');
  }

  print(newList);

  print('');

  final keys = nums.keys.map((e) => 'index: $e').toList();
  print(keys);

  print('');

  final values = nums.values.map((e) => '$e요').toList();
  print(values);
}

// 결과
{[1]: [하나], [2]: [둘], [3]: [셋]}
[1 - 하나, 2 - 둘, 3 - 셋]

[index: 1, index: 2, index: 3]

[하나요, 둘요, 셋요]

 

void main(List<String> args) {
  List<Map<String, String>> persons = [
    {'firstName': 'John', 'lastName': 'Doe'},
    {'firstName': 'Jane', 'lastName': 'Doe'},
    {'firstName': 'Baby', 'lastName': 'Doe'},
  ];

  var result = persons
      .where((element) => element['firstName'].toString().startsWith('J'))
      .toList();

  print(result);
}

// 결과
[{firstName: John, lastName: Doe}, {firstName: Jane, lastName: Doe}]

 

void main(List<String> args) {
  final words = ['안녕하세요', '저는', 'TB입니다'];

  // reduce 실행한 리스트가 String으로 구성되어 있으므로
  // 다른 type을 리턴할 수 없다.
  var wordsLen = words.reduce((v, e) => (v.length + e.length).toString());

  print('ssum of words length: ${int.parse(wordsLen)}');
}

// 결과
ssum of words length: 6

 

void main(List<String> args) {
  var someList = [1, 2, 3, 4, 5];

  // fold는 원하는 타입을 리턴할 수 있다.
  final sum = someList.fold(0, (prev, next) => prev + next);
  print(sum);

  print('');

  final words = ['안녕하세요', '저는', 'TB입니다'];

  final setence = words.fold('', (prev, next) => prev + next);
  print(setence);
  print('');

  final count = words.fold(0, (prev, next) => prev + next.length);

  print('length of $words is $count');
}

// 결과
15

안녕하세요저는TB입니다
length of [안녕하세요, 저는, TB입니다] is 12

 

// functional programming
// 1. 새로운 컬렉션 리턴
// 2. 메서드 체이닝 가능

void main(List<String> args) {
  final List<Map<String, String>> persons = [
    {'firstName': 'John', 'lastName': 'Doe'},
    {'firstName': 'Jane', 'lastName': 'Doe'},
    {'firstName': 'Baby', 'lastName': 'Doe'},
  ];

  final parsedPerson = persons
      .map((e) => Person(firstName: e['firstName']!, lastName: e['lastName']!))
      .toList();

  print(parsedPerson);

  print('');

  final baby = parsedPerson.where((e) => e.firstName == 'Baby');
  print(baby);
}

class Person {
  final String firstName;
  final String lastName;

  Person({required this.firstName, required this.lastName});

  @override
  String toString() => 'Person(firstName: $firstName, lastName: $lastName)';
}

// 결과
[Person(firstName: John, lastName: Doe), Person(firstName: Jane, lastName: Doe), Person(firstName: Baby, lastName: Doe)]

(Person(firstName: Baby, lastName: Doe))

 

void main(List<String> args) {
  var fruits = {
    'Apple': '사과',
    'Banana': '바나나',
    'Kiwi': '키위',
  };

  final newMap = fruits.entries.map((entry) {
    final key = entry.key;
    final value = entry.value;

    return '$key (eng) => $value (kor)';
  });

  print(newMap);

  print('');

  var newNums = [];

  List<Map<String, String>> nums = [
    {'one': '1'},
    {'two': '2'},
    {'three': '3'},
  ];

  for (var n in nums) {
    final num = n.entries.map((entry) {
      final key = entry.key;
      final value = entry.value;
      return '$key : $value';
    });
    newNums.add(num.toString().replaceAll('(', '').replaceAll(')', ''));
  }

  print(newNums);
}

// 결과
(Apple (eng) => 사과 (kor), Banana (eng) => 바나나 (kor), Kiwi (eng) => 키위 (kor))

[one : 1, two : 2, three : 3]

 

 

반응형

관련글 더보기

댓글 영역