LoginSignup
4
2

More than 3 years have passed since last update.

Dart オブジェクト内のリストのユニーク結合

Last updated at Posted at 2020-07-24

はじめに

最近、Flutterを業務でやり始めて早2ヶ月が経ちました。
FlutterでのWidget周りは調べながらわりと理解できてきたのですが、Dart言語自体の使い勝手がいまいちわからないことだらけの日々です。
今回もiOSの時と同じように自分の備忘録兼ねて残します。

Dartのリスト(array)加工

stack overflowで調べたりするとよく、forEachやforの記事が結構出てくるんですが、もはや最近はmap使いますよね。

var array1 = ['a', 'b', 'c', 'd', 'e'];

array1.map((e) => e + 'b')
// こちらも結果は上と同じ
array1.map((e) {
  return e + 'b';
      }
 )

// (ab, bb, cb, db, eb)
// (ab, bb, cb, db, eb)

こんな感じで(e)に配列の中身が一つずつ入ってくるので、それを使って加工することができます。
javascriptのアロー関数的なやつが使えるので、他に処理がなければ=>ですっきり書けますね。
ファットアロー記法と呼ばれているらしいです。

リストの中のリストやオブジェクトの中の結合ってどうやる?

というのが本題です。
簡単なリストの加工は問題ないけど、これどうやろうかな。Swiftならreduce、set,filterあたりで色々思いつくのですが。。。

例えば、以下のようなJsonがAPIから返ってくるとします。

{
  "test": {
   "strs": [
      "1","2"
    ]
  },
  "test": {
   "strs": [
      "3","1"
    ]
  },
 "test": {
   "strs": [
      "3","2"
    ]
  },
  ....
}

このJsonをデコードしてオブジェクトに格納する場合は、カスタムクラスは以下のようになります。
※Jsonのデシリアライズ処理は省きます。

class Test {
  final List<String> strs;

  Test({
    this.strs,
  });
}

先ほどのJsonからパースすると以下のようになります。

var testList = jsonパースする処理;
print(testList.toString());
// [Instance of 'Test', Instance of 'Test', Instance of 'Test']

そもそも論でいくと、APIから別でstrsの全種類を網羅したリストをjsonで返してもらうのがシンプルパターンかと思いますが、今回はそれは置いときます。
やりたいこととしては、

・Testクラスの中にあるstrsをまとめた1つのリストが欲しい。 (つまり、構造はシンプルな1次元のリスト構造)
・かつstrsは重複していることもあるのでユニークにしたい。

そんな時は、これです。

var testList = jsonパースする処理;
// こいつでまずstrsの配列に加工する
var result = testList.map((e) => e.strs);
// 結果: ([1, 2], [3, 1], [3, 2])

// 次にreduceを使ってすべてstrsの配列同士を結合する
var result2 = result.reduce((a, b) => a+b);
// 結果: [1, 2, 3, 1, 3, 2]

// 最後に.toSet()を使って重複を排除、それを.toList()で再びリスト型にキャストする
var result3 = result3.toSet().toList();
// 結果: [1, 2, 3]

めでたく、オブジェクト内のリストのユニーク結合ができました。
正確には、オブジェクトのリストを加工して、strsごとのリストを作り、それらを結合をしてからユニークなものにリデュース(減らす)するとなります。

まとめないと冗長なので最後に綺麗にして完成。

testList.map((e) => e.strs)
        .reduce((a, b) => a+b)
        .toSet().toList();

余談

最近知ったんですが、Dartって便利な演算子や記法が結構ありますよね。
その中でスプレット演算子なるものを知ったので載せておきます。

単純に結合したい場合は、変にするよりこのようにスプレット演算子を使用するのも良いと思います。
FlutterのRowやColumnのchildren[]で使ったりできるので、結構用途あるかと。

// スプレッド演算子
var l1 = [1, 2];
var l2 = [0, ...list1];
print(l2.length);
// 3

// null対応スプレッド演算子
var l3;
var l4 = [0, ...?l3];
print(l4.length);
// 1

参考記事

・リストでよく使うメソッドまとめ
Top 10 Array utility methods you should know (Dart)
・型について
おとなしく Dart のお勉強【型】

まとめ

調べればわかる内容だと思うので、改めて書くほどのことでもないかもしれませんが、
このあたりパッと出てくれば結構、ぐぐる時間削減できるので、など他の早く網羅したいものです。
もっといい方法ありましたらアドバイスお待ちしております。
最後までご覧いただきありがとうございました!

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2