2017-07-25 13 views
1

文字列val trackingHeader = "k1=v1, k2=v2, k3=v3, k4=v4"を解析し、Map(k1 -> v1, k2 -> v2, k3 -> v3, k4 -> v4)に変換します。続いて、私はこれを行うために使用されるコードです:
コレクションから「フィルタリングされた」アイテムにアクセスするにはどうすればよいですか?

val trackingHeadersMap = trackingHeader 
    .replaceAll("\\s", "") 
    .split(",") 
    .map(_ split "=") 
    .map { case Array(k, v) => (k, v) } 
    .toMap 

私は私の所望の出力を得ることができました。しかし、私はまた、val trackingHeader = "k1=v1, k2=v2, k3=v3, k4="のような不正な入力事件を処理する必要があります。キーk4の値がないことに注意してください。

val trackingHeadersMap = trackingHeader 
    .replaceAll("\\s", "") 
    .split(",") 
    .map(_ split "=") 
    .collect { case Array(k, v) => (k, v) } 
    .toMap 

グレート今(私はcollectを使用することにより、同様の不正なケースを処理しているが、私はこの問題を持っていたものの鍵を知っているしたいと思いますし、それをログに記録:私の上記のコードは、私はそれを変更しscala.MatchError: [Ljava.lang.String;@622a1e0c (of class [Ljava.lang.String;)と破壊を開始しますこの例ではk4)。私は、次を試してみましたが、望ましい結果を得ることができたが、それを行うには、その正しい方法かどうかはわからない:

val badKeys = trackingHeader 
    .replaceAll("\\s", "") 
    .split(",") 
    .map(_ split "=") 
    .filterNot(_.length == 2) 

今、私はbadKeysを反復処理し、それらをプリントアウトすることができます。これを行うより良い方法はありますか?

val trackingHeadersMap = trackingHeader 
    .replaceAll("\\s", "") 
    .split(",") 
    .map(_ split "=") 
    .map { 
    case v @ Array(k) => println(s"bad key: $k"); v 
    case v => v 
    }.collect { 
    case Array(k, v) => (k, v) 
    } 
    .toMap 

良好溶液(変換から副作用を分離:

+0

の。助けてくれた皆様に感謝します! –

答えて

2

あなたは結果をオプションにし、flatMapを使用することができます代わりに、ここでディマの答えと一緒に行くmap

.flatMap { 
    case Array(k, v) => Some(k -> v) 
    case Array(k) => println(s"Bad entry: $k"); None 
    } 
+0

パーフェクト。それがまさに私が必要としていたものです。ありがとうございました。 –

0

一つの解決策は、collectへの呼び出しの前に1要素の配列に一致する要素の悪いキーを印刷mapステップを追加することであろう))(「良い」と「悪い」2つのコレクションにこれを分割することになるpartitionを使用し、それぞれを個別に処理するために、次のようになります。

val (good, bad) = trackingHeader 
    .replaceAll("\\s", "") 
    .split(",") 
    .map(_ split "=") 
    .partition(_.length == 2) 

val trackingHeadersMap = good.map { case Array(k, v) => (k, v) }.toMap 

bad.map(_(0)).foreach(k => println(s"bad key: $k")) 
関連する問題