2016-08-09 8 views
2

私は一連のJsonオブジェクトを解析して、機能全体を取り消す可能性のある障害を解析しようとしています。潜在的な障害に対応する良い方法

理想的には、私のような何かをしたい:

fn .... -> Result<Vec<Video>, YoutubeParseError> { 
    ... 
    let videos = try!(doc.find("items"). 
     and_then(Json::as_array). 
     ok_or(YoutubeParseError)); 

    Ok(videos.into_iter(). 
     map(|item| try!(json_to_video(item))). 
     collect()) 
} 

しかし、もちろんトライの誤差にmap()を脱出し、代わりにResult<Vec<Video>,_>のはありませんが、私はVec<Result<Video,_>>を取得します。これを新しいvecに要素を追加する手動反復として書き直すことができましたが、これを処理する簡単な方法がないように感じられます。

Iter<Result<T>>からResult<Vec<T>,_>に簡単に入る機能がありますか?

+0

私は2番目の試しとは思わない!あなたが望むように動作します。試してみて!閉鎖のあなたを得るでしょう。ところで、あなたは 'flat_map'を見ましたか? – sgldiv

答えて

0

関数型プログラミング言語では、オプションと結果をコンテナとして扱うことができ、錆は似ているので、map/flat_mapを指定することができます。 flat_mapでこれを行うことができます。 videosが既にベクトルの場合は、Okの予想数をflat_mapのピッチ長に対してテストして、Okを返すかどうかを判断できます。

しかし、怠け者にして、最初の失敗後も解析を続行しないようにしてください。 take_whileはオプションです。いずれにしても、途中でparse_failureが見えたら追跡する必要があります。次のようなものが動作します - がErrorを落とす方法を示しますが、必要以上に解析します。また、解析結果に

fn get_videos(test: &Vec<&str>) -> Result<Vec<u32>, &'static str> { 
    let videos = ... 
    let expected = videos.len(); 
    let extracted = v.into_iter().flat_map(|x| json_to_video(x)).collect(); 
    if extracted.len() == expected { 
     Ok(extracted) 
    } else { 
     Err("__CANNOT_PARSE__") 
    } 
} 

を取得するために.filter、その後.mapを使用することができますここで遅延し、それを行うためのオプションです -

let extracted = videos.map(|x|json_to_video(x)) 
         .take_while(|x|x.is_ok()) 
         .map(|x|x.ok().unwrap()) 
         .collect() 

あなたが最初の失敗で始まるすべてのものを落としたとして、あなたはunwrapを呼び出すことができます。今戻すOkの場合extracted.len() == videos.len()

+0

@shepmaster ...書かれているように、最初の失敗を超えて解析します。 – sgldiv

+0

ああ、それは良い点です!混乱を避けるために私のコメントを明確にします。 – Shepmaster

関連する問題