형 변환
void main(){
//List to Map / Set
List<String> blackPink = ['로제','지수','리사','제니','제니'];
print(blackPink.asMap()); //{0: 로제, 1: 지수, 2: 리사, 3: 제니}
print(blackPink.toSet()); // {로제, 지수, 리사, 제니} >> 중복 제거됨
// Map to List
Map blackPinkMap = blackPink.asMap();
print(blackPinkMap.keys); // (0, 1, 2, 3, 4) iterable 이므로 주로 list로 변환하여 처리
print(blackPinkMap.keys.toList()); //[0, 1, 2, 3, 4]
print(blackPinkMap.values.toList()); //[로제, 지수, 리사, 제니, 제니]
// List to Set
Set blackPinkSet = Set.from(blackPink);
print(blackPinkSet); //{로제, 지수, 리사, 제니}
// Set to List
print(blackPinkSet.toList()); //[로제, 지수, 리사, 제니]
}
List.map()
void main() {
List<String> blackPink = ['로제', '지수', '리사', '제니'];
final newBlackPink = blackPink.map((x) {
return '블랙핑크 $x';
}); // map 을 사용하면 새로운 iterable 형태로 리턴됨
print(newBlackPink); //(블랙핑크 로제, 블랙핑크 지수, 블랙핑크 리사, 블랙핑크 제니) iterable 형태로 반환됨
print(newBlackPink.toList()); //[블랙핑크 로제, 블랙핑크 지수, 블랙핑크 리사, 블랙핑크 제니] List로 변환
final newBlackPink2 = blackPink.map((x)=> '블랙핑크 $x'); // arrow func으로 사용가능
print(newBlackPink2.toList()); // 데이터 쉬운 가공을 위해 list로 변환
print(newBlackPink == newBlackPink2); // false
//[1.jpg,3.jpg,5.jpg,7.jpg,9.jpg] 로 가공 예제
String number = '13579';
final parsed = number.split('').map((x)=>'${x}.jpg').toList();
print(parsed);
}
Map.map()
void main() {
Map<String, String> harryPotter = {
'Harry Potter': '해리포터',
'Ron Weasley': '론 위즐리',
'Hermione Granger': '헤르미온느 그레인저',
};
/*
* Map을 map()할때는 key,value를 모두 파라미터로 전달받는다.
* */
final result = harryPotter.map(
(key, value) => MapEntry(
'Harry Potter Character $key',
'해리포터 캐릭터 $value',
),
);
print(result); // {Harry Potter Character Harry Potter: 해리포터 캐릭터 해리포터, Harry Potter Character Ron Weasley: 해리포터 캐릭터 론 위즐리, Harry Potter Character Hermione Granger: 해리포터 캐릭터 헤르미온느 그레인저}
// Map의 key 나 values 값들을 변경하고싶을때
final keys = harryPotter.keys.map((x)=>'HPC $x').toList(); //[HPC Harry Potter, HPC Ron Weasley, HPC Hermione Granger]
final values = harryPotter.values.map((x)=>'해리포터 $x').toList(); // [해리포터 해리포터, 해리포터 론 위즐리, 해리포터 헤르미온느 그레인저]
}
Set.map()
void main() {
Set blackPinkSet = {
'로제','지수','제니','리사'
};
// Set > Set
final newSet = blackPinkSet.map((x)=>'블랙핑크 $x').toSet(); //{블랙핑크 로제, 블랙핑크 지수, 블랙핑크 제니, 블랙핑크 리사}
}
where
void main() {
List<Map<String,String>> people = [
{
'name' : '로제',
'group' : '블랙핑크',
},
{
'name' : '지수',
'group' : '블랙핑크',
},
{
'name' : 'RM',
'group' : 'BTS',
},
{
'name' : '뷔',
'group' : 'BTS',
}
];
// where 은 true 혹은 false를 리턴
final blackPink = people.where((x)=>x['group'] == '블랙핑크').toList(); //[{name: 로제, group: 블랙핑크}, {name: 지수, group: 블랙핑크}]
final bts = people.where((x)=>x['group'] == 'BTS').toList(); // [{name: RM, group: BTS}, {name: 뷔, group: BTS}]
}
reduce()
void main() {
List<int> numbers = [1,3,5,7,9];
final result = numbers.reduce((prev,next){
print('-----------------');
print('previous : $prev');
print('next: $next');
print('total: ${prev + next}');
return prev + next;
});
print(result); // 25
List<String> words = [
'안녕하세요 ',
'저는',
' Dylan 입니다'
];
final sentence = words.reduce((prev,next)=>prev+next);
print(sentence); //안녕하세요 저는 Dylan 입니다
/*
* 기존 List words는 String 으로 선언되었는데 return을 int로 하면 에러 발생
* reduce는 선언된 타입 그대로 리턴해야함
* */
words.reduce((prev,next)=> prev.length + next.length); // error
}
fold() – reduce와 비슷하나 return 값을 지정가능
void main() {
List<int> numbers = [1, 3, 5, 7, 9];
/*
* reduce 는 동일한 타입을 리턴 해야하지만, fold 는 리턴할 타입을 직접 지정할 수 있음
* fold prev에 첫번째 제공한 파라미터가 들어감(아래코드에서는 0)
* */
final sum = numbers.fold<int>(0, (prev, next) => prev + next);
print(sum); //25
List<String> words = [
'안녕하세요 ? ',
'저는 ',
'Dylan 입니다.',
];
final sentence = words.fold<String>('', (prev, next) => prev + next);
print(sentence); //안녕하세요 ? 저는 Dylan 입니다.
/*
* words의 모든 글자의 길이 세기
* 기존 reduce로 불가능한 것이 fold로는 가능
* */
final count = words.fold<int>(0, (prev, next) => prev + next.length);
print(count); // 21
}
cascading operator
void main() {
List<int> even = [2, 4, 6, 8];
List<int> odd = [1, 3, 5, 7];
print([even,odd]); //[[2, 4, 6, 8], [1, 3, 5, 7]]
/*
* cascading operator
* 값을 펼쳐서 넣을때
* 새로운 리스트로 반환하므로 기존 even 리스트와 다름
* */
print([...even,...odd]); //[2, 4, 6, 8, 1, 3, 5, 7]
print(even == [...even]); // false
}
유용한 팁
void main() {
/*
* 다른 서버로부터 들어온 데이터를 키의 스펠링이 맞는지 틀렸는지 등 100% 신뢰할 수 없음.
* 그래서 일반적으로 미리 class를 정의해두고 instance로 구조화 하여 사용
* 아래 people 데이터가 서버로 부터 들어온 데이터라고 가정
* */
List<Map<String, String>> people = [
{
'name': '로제',
'group': '블랙핑크',
},
{
'name': '지수',
'group': '블랙핑크',
},
{
'name': 'RM',
'group': 'BTS',
},
{
'name': '뷔',
'group': 'BTS',
}
];
// 데이터를 인스턴스로 가공
final parsedPeople = people
.map((x) => Person(
name: x['name']!,
group: x['group']!,
))
.toList();
print(
parsedPeople); //[Instance of 'Person', Instance of 'Person', Instance of 'Person', Instance of 'Person']
for (Person person in parsedPeople) {
print(person.name);
print(person.group);
}
final bts = parsedPeople.where((x) => x.group == 'BTS');
print(bts); //(Person(name:RM,group:BTS), Person(name:뷔,group:BTS))
// 새로운 값을 리턴해주므로 한번에 체이닝도 가능
final result = people
.map((x) => Person(
name: x['name']!,
group: x['group']!,
))
.where((x) => x.group == 'BTS')
.fold<int>(0, (prev, next) => prev + next.name.length);
print(result); //3
}
class Person {
final String name;
final String group;
Person({
required this.name,
required this.group,
});
}