teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

クラスで扱う例を追記

2020/09/17 13:44

投稿

nskhei
nskhei

スコア704

answer CHANGED
@@ -15,4 +15,121 @@
15
15
  );
16
16
  }
17
17
  }
18
+ ```
19
+
20
+ また、根本的な問題になりますが、このようなネストしたデータは、クラスに変換して扱った方が良いです。
21
+
22
+ どんなアプリを作っているか分からないので大体の雰囲気だけ示すと、以下のような感じです。
23
+
24
+ ```dart
25
+
26
+ // ユーザーを表すクラス
27
+ class User {
28
+ final String key;
29
+ final String name;
30
+ final Sex sex;
31
+ final List<WeightData> weightHistory;
32
+
33
+ User({
34
+ this.key,
35
+ this.name,
36
+ this.sex,
37
+ this.weightHistory,
38
+ });
39
+ }
40
+
41
+ // 体重データを表すクラス
42
+ class WeightData {
43
+ final double value;
44
+ final DateTime date;
45
+
46
+ WeightData({
47
+ this.value,
48
+ this.date,
49
+ });
50
+ }
51
+
52
+ // 性別を表すEnum
53
+ enum Sex {
54
+ Male,
55
+ Female,
56
+ Unknown,
57
+ }
58
+
59
+ // これらを使うと、データはこんな感じで表現できる
60
+ final List<User> allData = [
61
+ User(
62
+ key: '1',
63
+ name: 'Jim',
64
+ sex: Sex.Male,
65
+ weightHistory: [
66
+ WeightData(
67
+ date: DateTime(2020, 8, 25),
68
+ value: 5.1,
69
+ ),
70
+ WeightData(
71
+ date: DateTime(2020, 8, 26),
72
+ value: 5.4,
73
+ ),
74
+ ],
75
+ ),
76
+ User(
77
+ key: '2',
78
+ name: 'Tom',
79
+ sex: Sex.Male,
80
+ weightHistory: [
81
+ WeightData(
82
+ date: DateTime(2020, 8, 25),
83
+ value: 5.1,
84
+ ),
85
+ WeightData(
86
+ date: DateTime(2020, 8, 26),
87
+ value: 5.4,
88
+ ),
89
+ ],
90
+ ),
91
+ ];
92
+
93
+ // 実際の使用例
94
+ class ExamplePage extends StatefulWidget {
95
+ final String name;
96
+
97
+ const ExamplePage({
98
+ Key key,
99
+ @required this.name,
100
+ }) : super(key: key);
101
+
102
+ @override
103
+ _ExamplePageState createState() => _ExamplePageState();
104
+ }
105
+
106
+ class _ExamplePageState extends State<ExamplePage> {
107
+ List<DataPoint<DateTime>> data;
108
+
109
+ @override
110
+ void initState() {
111
+ super.initState();
112
+ this.data = allData
113
+ .where((user) => user.name == widget.name)
114
+ .map((user) => user.weightHistory)
115
+ .expand((data) => data)
116
+ .map(
117
+ (data) => DataPoint<DateTime>(
118
+ value: data.value,
119
+ xAxis: data.date,
120
+ ),
121
+ )
122
+ .toList();
123
+ }
124
+
125
+ @override
126
+ Widget build(BuildContext context) {
127
+ return Scaffold(
128
+ body: Center(
129
+ child: Text('${data[0]}'),
130
+ ),
131
+ );
132
+ }
133
+ }
134
+
18
135
  ```

1

コード修正

2020/09/17 13:44

投稿

nskhei
nskhei

スコア704

answer CHANGED
@@ -1,9 +1,11 @@
1
1
  `Map`型からvalueの部分だけを取り出すには、`values`という便利なプロパティが使えます。
2
2
 
3
3
  ```dart
4
- final weightData =
4
+ for (int i = 0; i < allData.length; i++) {
5
- (allData[i]['data'] as Map<String, Map<String, Map>>)['weight'];
5
+ final info = allData[i]['data'] as Map<String, dynamic>;
6
+ if (info['name'] != widget.name) continue;
6
7
 
8
+ final weightData = info['weight'] as Map<String, Map>;
7
9
  for (var value in weightData.values) {
8
10
  data.add(
9
11
  DataPoint<DateTime>(
@@ -12,4 +14,5 @@
12
14
  ),
13
15
  );
14
16
  }
17
+ }
15
18
  ```