多次元配列を並び替えたい
- 評価
- クリップ 0
- VIEW 382
実現したいこと
二次元配列を各要素の二つ目の要素を元に降順で並び替えたいです。
以下のようなコードを書いたのですがエラーになってしまいました。
var array = [["長男",0],["次男",7],["三男",3],["四男",10],["五男",5]]
array = array.sort{$0[1] as? Int > $1[1] as? Int} //ここでエラー
//実現したい結果は array = [["四男",10],["次男",7],["五男",5],["三男",3],["長男",0]]
Binary operator '>' cannot be applied to two 'Int?' operands
オプショナル型で演算子を適用できないということだと思うのですが、解決方法がわかりませんでした。
初歩的ではありますがご教授いただけると幸いです。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+3
e as? T
は「T型かも知れないしそうでないかも知れないような値をOptional<T>に変換」という書き方だと思います。
var a: Any = 1
var b = a as? Int
print(type(of: b)) // => Optional<Int>
ご質問にある通りOptional<Int>どうしを<
演算子で比較するのはいけないことになってますのでOptional<Int>ではなくInt型へ変換せねばなりません。
array.sort{$0[1] as! Int > $1[1] as! Int}
とすればそれができますが、これはプログラマーが絶対に型の変換が成功すると確信した上で使うものですので、万一Int型でないものを変換しようとした場合は実行時エラーが起きます。
https://docs.swift.org/swift-book/LanguageGuide/TypeCasting.html
質問意図とは外れますが、異なる型の値の集まりをArrayで表現するのは(静的型付けかつ優れた型推論能力を持っている)swift言語では下策に思えます。Arrayは全ての型が共通の場合のコレクションなので型が不一致のものを無理にまとめると要素の型がAnyとなってしまいます。本当はStringとIntの組であるにもかかわらず型の情報が消えてしまいますので不必要にキャストを使う羽目になります。
一般的になんらかの構造を表現するにはclass/structを用いることが多いと思いますが、コード内のごく狭い範囲でのみ用いるその場限りの構造を一々class/structとして宣言するのは面倒です。そんな場合はArrayではなくTupleを使ったほうがよいと思います。本件の場合なら「二次元配列」ではなく「Tupleの配列」とするわけです。Tupleなら要素の位置ごと(最初の要素、二番目の要素、...)に個別に型を推論してくれますので、本件のようなデータの場合だとarrayの各要素が「StringとIntの組」であると型推論してくれ型の曖昧性を排除できます。自然、不必要なキャストもなくなります。
var array = [("長男", 0), ("次男", 7), ("三男", 3), ("四男", 10), ("五男", 5)]
print(type(of: array)) // => Array<(String, Int)>
array.sort{$0.1 > $1.1}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
回答とはずれますが、大切なお話です。
こんな無駄な努力をしてまで無意味な配列を使う必要があるでしょうか?
その配列はstructであるべきものです。
そこで配列を使うのは筋が悪すぎます。
僕ならこうします。
struct Hoge {
let typeName: String
let number: Int
}
extension Hoge {
// このイニシャライザは仕様が分からないので仕方がなく作った。 できれば削除したい
init?(array: [Any]) {
guard array.count == 2 else { return nil }
guard let typeName = array[0] as? String,
let number = array[1] as? Int else { return nil }
self.typeName = typeName
self.number = number
}
}
// var は極力使わない。 変数を使いまわさない。
let array = [["長男",0],["次男",7],["三男",3],["四男",10],["五男",5]]
let array2 = array.compactMap(Hoge.init).sorted { $0.number > $1.number }
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.23%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
fuzzball
2019/02/06 09:19
質問内容が「多次元配列の並べ替え」では無いのでタイトルを修正して下さい。