2017-11-10 5 views
0

私はフィルタリングしようとする配列(オプションです)を持っています。その配列の内部にはカスタム構造体のインスタンスがあります。彼らはdistanceプロパティを持っています。これはStringです。現在、配列をフィルタリングする条件は、これらの文字列があるfloat値(distance)以下であることです。ここでは、コードは次のとおりです。私はそれを実装する場合オプションのラップを解除しようとすると、私のSwiftアプリケーションが致命的なエラーを発生させるのはなぜですか?

filteredUnitRestaurants = anotherUnitRestaurant?.filter({ (restaurant) -> Bool in 
    print (restaurant.distance) 
    return Float(restaurant.distance)! <= Float(distance) 
}) 

、Xcodeは(論理式の行に)オプションの値をアンラップしながら、それが予期せずにnilを見つけたことを言っている、エラーがスローされます。しかし、それはゼロではありませんので、print方法は、distance値を出力しますが、私はこのようなprint文を変更する場合:

print (Float(restaurant.distance)!) 

それはあまりにも、エラーがスローされます。だから、私は問題が浮動小数点値に文字列の値を変換することに関連していると思うが、distanceの値は単なる数値です。コンソールに印刷すると、次のようになります。Optional(10999.795970332603)

Xcodeが何を不快にさせるのか分かりません。何か提案はありますか?

+2

「restaurant.distance」はどのように設定していますか? "Optional("はおそらく文字列の一部なので、floatを作成することはできません。 – dan

+0

@dan、そうです、私は2つの場所の間の距離を見つけることでそれを取得します。これを保存するには、その型をStringに変更しますが、Stringの初期化子は、 "オプション("数字の前にあるもの。 –

答えて

3

を不要な作業をしているあなたはFloat(restaurant.distance)!restaurant.distanceをアンラップされていないため、コンパイラは、フロートタイプString?で形成することができないというエラーがスローされているだろう。しかし、文字列自体がOptional(10999.795970332603)として保存されていると思うようには思えませんでした。ダンはあなたの質問にコメントで指摘しました。有効な番号を保持するように変更し、変換をFloatに渡します。 Paulw11が指摘したように正確さは失われますが、少なくともクラッシュすることはありません。また、ゼロを見つけたときにクラッシュすることを避けるために、強制アンラッピングの代わりにif letを使用してみてください。

+0

はい、正しくあります.2つの場所間の距離を見つけることによって 'distance'を取得します。私はその型をStringに変更しますが、Stringの初期化子は '' distance(from:) 'メソッドからの距離を得るため、" Optional( "数字の前にあるものです。 –

2

あなたは何かが!でアンラップ力によってnilた場合をクラッシュさせるスウィフトを告げたので、基本的にあなたがクラッシュを取得しています。

nilなぜあなたはFloatに変換することができますので、私は言うことはできません。おそらくそれはデータのいくつかの他のビットでクラッシュしているか、おそらく文字列は文字通りOptional(10999.795970332603)です。この場合、値を正しくアンラッピングせずに文字列値を作成している場所に問題があります。

restaurant.distanceは、実際にはOptional(10999.795970332603)を含む文字列ではないオプションの文字列(つまり、String?)であると仮定すると、防御的にコード化し、条件付きアンラッピングを使用する必要があります。

Floatの代わりにDoubleを使用することもできます。 Floatはわずか32ビットであり、多くの精度が失われています。 Floatとしての10999.795970332603は10999.8であり、Doubleでは10999.7959703326である。

最後に、フィルタリングする前にdistanceDoubleに変換してください。あなたのrestaurant.distanceはオプションの文字列だった場合は、それぞれの時間が

それを変換
let doubleDistance = Double(distance) 
filteredUnitRestaurants = anotherUnitRestaurant?.filter({ (restaurant) -> Bool in 
    guard let distanceStr = restaurant.distance, 
      let restaurantDistance = Double(distanceStr) else { 
       return false 
    } 
    return restaurantDistance <= doubleDistance 
}) 
関連する問題