質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

1012閲覧

多次元配列を並び替えたい

testyoutatsu

総合スコア29

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/02/05 22:25

編集2019/02/05 22:32

###実現したいこと

二次元配列を各要素の二つ目の要素を元に降順で並び替えたいです。

以下のようなコードを書いたのですがエラーになってしまいました。

Swift

1var array = [["長男",0],["次男",7],["三男",3],["四男",10],["五男",5]] 2 3array = array.sort{$0[1] as? Int > $1[1] as? Int} //ここでエラー 4 5 6//実現したい結果は array = [["四男",10],["次男",7],["五男",5],["三男",3],["長男",0]]

errorMessage

1Binary operator '>' cannot be applied to two 'Int?' operands

オプショナル型で演算子を適用できないということだと思うのですが、解決方法がわかりませんでした。
初歩的ではありますがご教授いただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2019/02/06 00:19

質問内容が「多次元配列の並べ替え」では無いのでタイトルを修正して下さい。
guest

回答2

0

ベストアンサー

e as? Tは「T型かも知れないしそうでないかも知れないような値をOptional<T>に変換」という書き方だと思います。

swfit

1var a: Any = 1 2var b = a as? Int 3print(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の組」であると型推論してくれ型の曖昧性を排除できます。自然、不必要なキャストもなくなります。

swift

1var array = [("長男", 0), ("次男", 7), ("三男", 3), ("四男", 10), ("五男", 5)] 2print(type(of: array)) // => Array<(String, Int)> 3array.sort{$0.1 > $1.1}

投稿2019/02/05 23:58

編集2019/02/06 00:01
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

testyoutatsu

2019/02/06 00:34

丁寧な回答ありがとうございます。 >質問意図とは外れますが... 基礎をちゃんと理解する上でとてもためになりました。 やはりTupleを使うべきなんですね。無理に配列で...と考えていましたがそれぞれの性質をわかっていませんでした。 勉強になりました!ありがとうございました。
guest

0

回答とはずれますが、大切なお話です。

こんな無駄な努力をしてまで無意味な配列を使う必要があるでしょうか?
その配列はstructであるべきものです。
そこで配列を使うのは筋が悪すぎます。

僕ならこうします。

swift

1struct Hoge { 2 let typeName: String 3 let number: Int 4} 5 6extension Hoge { 7 // このイニシャライザは仕様が分からないので仕方がなく作った。 できれば削除したい 8 init?(array: [Any]) { 9 guard array.count == 2 else { return nil } 10 guard let typeName = array[0] as? String, 11 let number = array[1] as? Int else { return nil } 12 13 self.typeName = typeName 14 self.number = number 15 } 16} 17 18 19 20// var は極力使わない。 変数を使いまわさない。 21let array = [["長男",0],["次男",7],["三男",3],["四男",10],["五男",5]] 22 23let array2 = array.compactMap(Hoge.init).sorted { $0.number > $1.number }

投稿2019/02/06 00:11

MasakiHori

総合スコア3384

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問