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

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

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

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

Swift

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

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

1116閲覧

Swiftでの辞書を内包する配列の重複データの操作について

swifty

総合スコア38

Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

Swift

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

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2019/08/24 05:32

実現したいこと

現在realmDBにあるデータを検索し検索結果を表示する機能を実装しています。そこで大量にある辞書を内包する配列データの中から不要なデータは取り除き必要なデータだけを抽出する必要が出ています。どういったデータを抽出したいかは以下に詳細を記述しております。

ソースコード

Swift

1 2let fetchedRecordDataArray = self.realm.objects(RecordData.self).sorted(byKeyPath: "savedTime", ascending: false) 3 4if fetchedRecordDataArray .isEmpty { 5 6} else { 7 8 dump(fetchedRecordDataArray) 9 10 for fetchedRecordData in fetchedRecordDataArray { 11 12 //検索結果を表示するためのDataSourceであるoriginalDataSourceに追加していく 13 originalDataSource.append("(fetchedRecordData.recordDate) : (fetchedRecordData.text)") 14 15 } 16}

上のソースコード内の

dump(fetchedRecordDataArray)

の結果が以下のようになっています。1000以上のデータがあるのをわかりやすくするためここでは始めの3つのデータだけ記しています。

fetchedRecordDataArray

1Results<RecordData> <0x7fc8584ad5f0> ( 2 [0] RecordData { 3 id = 7F140D6D-337E-4585-A3C9-160358523B80; 4 recordDate = 8/23/2019; 5 text = test1; 6 savedTime = 2019-08-22 15:04:00 +0000; 7 isDeleted = 0; 8 }, 9 [1] RecordData { 10 id = 69D950E8-3083-4F38-8EC3-6339B9483E42; 11 recordDate = 8/22/2019; 12 text = test2; 13 savedTime = 2019-08-22 15:03:41 +0000; 14 isDeleted = 0; 15 }, 16 [2] RecordData { 17 id = 01E80873-0D89-41ED-8360-FC152307D3B2; 18 recordDate = 8/22/2019; 19 text = test3; 20 savedTime = 2019-08-22 12:28:22 +0000; 21 isDeleted = 0; 22 } 23 . 24 . 25 . 26 27) #1

現在だと端末の画面で検索結果で表示される検索結果が以下のようになります。

8/23/2019 : test1 8/22/2019 : test2 8/22/2019 : test3 . . .

この結果が以下のようにrecordDateが同じものであれば、その中でsavedTimeが最新のものだけを抽出するという操作をしたいです。ですがその方法がわかりかねております。どのようにすれば実現できますでしょうか?皆様のお力添えいただけますと幸いです。

8/23/2019 : test1 8/22/2019 : test2 . . .

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

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

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

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

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

guest

回答2

0

うまくそれを一発で検索する方法はなかなか思いつかないです。
手の込んだ検索方法(毎回1日1日検索し、配列に追加していく)は
繰り返し処理により負荷が大きくなり、時間がかかってしまいそうです。

なので、isLatest(仮)のbool値を各データに追加することで解決するのはどうでしょう?
同日でもっとも新しいのはisLatest=true, 同日の古いデータはisLatest=false、
isLatest=trueで検索し、データを取得すれば解決ですね。

なので、まず前処理として
今の全データにisLatest=true, falseを入力することですね。
マイグレーションは面倒なので、
新たに違うクラスを作って行うのが楽だと思います。
それとも、元データからRealmに登録する時の方法を変えるかですね。

その後は新たなデータは登録時にisLatestをcheckするようにするか、
できないようなら、前回データ処理以降だけを取得できるように
処理時の日時をどこかに保存するようにしてくださいね。

isLatest=true, falseを判定・登録する方法は
工夫のしどこ(楽しいとこ)だと思うので、考えてみてくださいね。

力技で1日1日検索するのでもできますけどね。

投稿2019/08/25 01:21

hameji

総合スコア1380

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

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

swifty

2019/08/25 03:48

ご回答ありがとうございます。 "isLatest(仮)のbool値を各データに追加することで解決するのはどうでしょう?同日でもっとも新しいのはisLatest=true, 同日の古いデータはisLatest=false、isLatest=trueで検索し、データを取得すれば解決" →たしかにisLatestプロパティさえ追加してしまえば取得は簡単ですね。 "今の全データにisLatest=true, falseを入力することですね。マイグレーションは面倒なので、新たに違うクラスを作って行うのが楽だと思います。それとも、元データからRealmに登録する時の方法を変えるかですね。" →マイグレーションを今までしたことがなく、できればしたくないと思っていました。もしマイグレーションしてしまうなら"元データからRealmに登録する時の方法を変える"がいいかもしれないと思っております。 でももしマイグレーションしなくても済むのであればその方法に興味があるのですが"新たに違うクラスを作って行う"ということがどういうことかイメージがわきかねる状況です。 現在のデータが保存されている RecordData というクラスの他に RecordData2(仮) を作ってそこに保存し直すということですよね?そうなった場合はRecordData2作成以降のデータは登録時にisLatestをcheckするようにすればいいので問題なさそうで、今後データの表示や検索にはRecordDataではなくRecordData2を使うという理解でよろしいでしょうか?ただその場合それまでに保存されているRecordDataの全てのデータをRecordData2にisLatestの結果も含めて追加する必要がありますよね?その作業が難しそうだなとは思っているのですがやるしかないのでしょうか... Realmのマイグレーションも含めてもう1度考え直したいとは思います。
hameji

2019/08/25 04:40

自分もマイグレーションした事ないんですが、 (面倒そうなので避けてました) 今後リリース後にデータ構造を変えることを考えると絶対に必要ですよね。 なのでこれをいい機会に勉強するのがいいと思いますが嫌なら書かれてるようにrecorddata2に保存し直すことですね。 いずれにしろ一個一個データをチェックして、isLatestを書き換えないとですけどね。 for分かwhile分, もしくはmapなどをうまく組み合わせればそれほどのコード量にならないと思いますよ。 マイグレーションの参考になりそうなHP https://rara-world.com/
swifty

2019/08/25 04:59

お世話になっております。 さようでしたか。ちなみにこちらのアプリは既にリリース済みでして個人開発で初めてリリースしたアプリでSaaSなのでできるだけマイグレーションによるリスクを冒したくはないと思っておりました。 ただたしかにおっしゃる通りで今後絶対にマイグレーションは避けて通れないだろうとは思っていたところでもあるのでよい機会でもあるのではないかと前向きに考えようとは思っております。 "いずれにしろ一個一個データをチェックして、isLatestを書き換えないとですけどね" →やはりそうですよね。なるほど。 参考リンクもありがとうございます。引き続きどうすべきかもう少し対応策を練ってみます。 ありがとうございました!
hameji

2019/08/25 05:14

多少のアドバイスまでに 自分なら まず、isLatest=trueで全部に登録 全件を時間順に取得 そのデータを1個ずつ後ろと比較して同日ならfalseに上書きするですね。 負荷としてはそんなでもないと思いますよ。 検索は1回ですし。 なんで先々にそういう想定してデータモデル作らなかったのか、 自分って馬鹿だなって思いますよね… 自分はそれで行ったり来たりを繰り返してて、 まだリリースに至れてない状態です。 お互い頑張りましょう!
swifty

2019/08/25 05:28

アドバイスありがとうございます! isLatestプロパティを追加する案で攻めるのであればそれがベストかもしれないですね。 "なんで先々にそういう想定してデータモデル作らなかったのか、 自分って馬鹿だなって思いますよね…" →おっしゃる通りです。そのときも他の観点からなど考慮してこの形がベストだと思ってこうしたのですが、こういった問題にぶつかるとは思っていませんでした。savedTimeさえ保存しておけば最新のデータわかるし大丈夫だろうと思っていました..笑 "自分はそれで行ったり来たりを繰り返してて、まだリリースに至れてない状態です。お互い頑張りましょう!" →はい!そうしましょう!リリースした後もPR作業やバージョンアップの開発に追われますが本当に楽しいです!今後ともよろしくお願いします!
swifty

2019/08/25 07:05

先ほどの問題ですが、考えに考えたあげくマイグレーションも、新しいプロパティの追加もせず無事解決することができました!いずれにしろhamejiさんとのやり取りをしていく中で自分の頭の中で問題点がクリアになっていき解決することができました。ご協力ありがとうございました!
guest

0

自己解決

該当箇所を以下のように記述することで無事解決させることができました!

Swift

1let fetchedRecordDataArray = self.realm.objects(RecordData.self).sorted(byKeyPath: "savedTime", ascending: false) 2 3if fetchedRecordDataArray .isEmpty { 4 5} else { 6 7 dump(fetchedRecordDataArray) 8 9 var uniqueDateArray = [String]() 10 11 for fetchedRecordData in fetchedRecordDataArray { 12 13 //もしrecordDateがまだ追加されていなければそのrecordDateを追加し、かつ検索結果を表示するためのoriginalDataSourceにも追加していく 14 if uniqueDateArray.contains(fetchedRecordData.recordDate) == false { 15 16 uniqueDateArray.append(fetchedRecordData.recordDate) 17 18 originalDataSource.append("(fetchedRecordData.recordDate) : (fetchedRecordData.text)") 19 20 } 21 } 22}

投稿2019/08/25 07:03

編集2019/08/25 08:54
swifty

総合スコア38

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問