【Swift】2次元配列 で 転置行列 ( transpose matrix )

これやりたくなるときありますよね。

転置行列(てんちぎょうれつ、英: transpose [of a matrix], transposed matrix)とは、m 行 n 列の行列 A に対して A の (i, j) 要素と (j, i) 要素を入れ替えてできる n 行 m 列の行列のことである。転置行列は tA, AT, A⊤, Atr, A′ などと示される。行列の転置行列を与える操作のことを転置(てんち、英: transpose)といい、「A を転置する」などと表現する

👉 転置行列 - Wikipedia hatena-bookmark

これを、変換すると、


[
  [1, 2, 3, 4, 5], 
  ["A", "B", "C", "D", "E"],
  ["あ", "い", "う", "え", "お"],
  ["か", "き", "く", "け", "こ"]
]

こうなるやつ。


[
  [1, "A", "あ", "か"],
  [2, "B", "い", "き"],
  [3, "C", "う", "く"],
  [4, "D", "え", "け"],
  [5, "E", "お", "こ"]
]

Swift で、extension で、やってみます。

 

🔄 配列系のプロトコルは多すぎないか

Xcode の反応をみながら、とりあえずいけた。

縦横インデックスを

きれいに .indecies で取りたかったけど、

うまく取れなかった。


extension Collection where Element: Collection,
                           Self.Index == Int, Element.Index == Int {

  func transposed1() -> [[Element.Element]] {
    let cols = 0 ..< (self.first?.count ?? 0)
    let rows = 0 ..< self.count
    var result: [[Element.Element]] = []
    for col in cols {
      var newRow: [Element.Element] = []
      for row in rows {
        newRow.append(self[row][col])
      }
      result.append(newRow)
    }
    return result
  }

}

// [[1, "A", "あ", "か"], [2, "B", "い", "き"], [3, "C", "う", "く"], [4, "D", "え", "け"], [5, "E", "お", "こ"]]

Array とか Collection。

where 句 や Element。

書きながらでないと、きっと理解できない感じがする。

👉 Collection | Apple Developer Documentation hatena-bookmark

 

🔄 for ループ を map に

「空配列を作成して要素追加」てのがなんとなくだるいので、

map を使います。

入れ子なので「$0」は使いません。


func transposed2() -> [[Element.Element]] {
  let cols = 0 ..< (self.first?.count ?? 0)
  let rows = 0 ..< self.count
  return cols.map { col in
    rows.map { row in
      self[row][col]
    }
  }
}

すぐに、return から始めたいので、

最初の let を省略。


func transposed3() -> [[Element.Element]] {
  return (0 ..< (first?.count ?? 0)).map { col in
    (0 ..< count).map { row in
      self[row][col]
    }
  }
}

ここまででいいか。

 

🔄 まとめ

まとめておきます。

また、勉強したら更新します。

Swift の「プロトコル」ってなんか高級。

👉 あなたの知らないCollectionの世界 #Swift - Qiita hatena-bookmark


【Swift】なんとなくメソッド名が長い気がする

慣れかもしれんけども、

メソッド名、というか、

メソッド名 + 省略できない引数名、というか。

全般的に長い。

つい作ってしまう。


extension String {
  func trim(_ chars: CharacterSet = .whitespaces) -> String {
    self.trimmingCharacters(in: chars)
  }
  func separatedBy(_ separator: String) -> [String] {
    self.components(separatedBy: separator)
  }
}

しかし、クラス名を省略できるのもいいところ。

みなさんは、どう思ってますか ?

 

2024-01-30 追記:

やっぱり長すぎ。なんなのこれ。

エディタに収まらなくね?

インデント2でも改行入れる隙がまったくない。

短い別名とか付けるの?


【SwiftData】 データストアファイルを SQLite コマンドで見てみる

そもそものきっかけは、

「Preview と シュミレーター の保存データは違うのか」

という素朴な疑問から。

 

📂 データファイルはどこにあるのか

xcrun で調べたみたが、パスが深くて長いし、

デバイスやアプリのIDがあれこれ違うので面倒すぎる。

コード内から吐かすのが楽ちん。


FileManager
  .default
  .urls(for: .applicationSupportDirectory, in: .userDomainMask)
  .last!
  .path(percentEncoded: false)

👉 Where does SwiftData store the data? | Apple Developer Forums hatena-bookmark

とか、いや、


URL.applicationSupportDirectory
  .path(percentEncoded: false)

で取得できるので print() などで出力。


// Playground
/Users/{USER_NAME}/Library/
  Application Support/

// Preview
/Users/{USER_NAME}/Library/Developer/
  Xcode/UserData/Previews/
  Simulator Devices/{DEVICE_ID}/
  data/Containers/Data/Application/{APP_ID}/Library/
  Application Support/

// Simulator
/Users/{USER_NAME}/Library/Developer/
  CoreSimulator/
  Devices/{DEVICE_ID}/
  data/Containers/Data/Application/{APP_ID}/Library/
  Application Support/

見づらいので改行しています。

実行環境で違うのか。

それぞれの「Application Support」 ディレクトリ以下に該当ファイルがある。


default.store
default.store-shm
default.store-wal

 

📂 SQLite コマンドで見てみる

👉 sqlite — Homebrew Formulae hatena-bookmark

せっかくなので覗く。


$ sqlite default.store

SQLite version 3.43.2 2023-10-10 13:08:14
Enter ".help" for usage hints.

sqlite> .tables
ACHANGE             ATRANSACTIONSTRING  ZTODO               Z_MODELCACHE
ATRANSACTION        Z_METADATA          Z_PRIMARYKEY

sqlite> .schema ZTODO
CREATE TABLE ZTODO ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZTIME TIMESTAMP, ZTEXT VARCHAR );

sqlite> .headers on
sqlite> .mode column

sqlite> select * from ZTODO;
Z_PK  Z_ENT  Z_OPT  ZTIME             ZTEXT
----  -----  -----  ----------------  -----------------------------------------------------------
11    2      1      727759392.308872  2. Do, or do not. There is no try.
12    2      1      727759392.914907  3. Most things look better when you put them in a circle.
13    2      1      727759393.191901  4. Could not get advice.
14    2      1      727760485.069984  0. You're not that important; it's what you do that counts.
15    2      1      727760485.781123  1. Most things done in secrecy are better left undone.
16    2      1      727760486.503812  2. When in doubt, just take the next small step.
17    2      1      727760487.112024  3. Have a firm handshake.

よくできてるなあ、SwiftData って。