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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

Q&A

解決済

3回答

1467閲覧

Array.sortの引数Comparison<T>を何回通ったのかが知りたい。

asus2

総合スコア22

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

0グッド

0クリップ

投稿2018/12/26 05:37

編集2018/12/26 06:00

お世話になります。

ProgressBarの下に進捗表示のためArray.Sortのソート条件Comparison<T>を何回通ったかを取得したいのですが、
ComparsionASCの引数に呼び出し元のFormを追加して、カウント値を適宜更新するようなことを考えましたが、
そもそもComparsionASCにはもう引数を追加できませんでした…なにかいい方法はないでしょうか。

c#

1//呼び出し元 2FormCommon common = new FormCommon(); 3 4public void Hoge(){ 5 Array.Sort(Array, common.ComparsionASC); 6} 7 8 9//呼び出されたComparsion 10public int ComparsionASC(string fileX, string fileY) 11{ 12 DateTime datetimeX = GetFileCreateOrRenovationDateTime(fileX); 13 DateTime datetimeY = GetFileCreateOrRenovationDateTime(fileY); 14 15 return DateTime.Compare(datetimeX, datetimeY); 16}

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

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

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

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

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

x_x

2018/12/26 06:09

進捗といいますが、何回で終了するかわからないのではカウントしても意味がないのでは?
Zuishin

2018/12/26 06:12

進展表示のためということですが、ソートするために比較関数が何回呼ばれるかは不定です。 ですから、目的となる回数を概算で求め、終了時に調整する必要があります。 また要素数がちょっとやそっとの量では進展率の表示をしなければならないほどの時間はかかりません。逆に入れるだけ遅くなって損ということにもなりかねません。 また、比較関数の効率が非常に悪いように見えます。何度も繰り返し文字列をパースしているので、この場合は LINQ を使って工夫すれば劇的に速くなる可能性もあります。
asus2

2018/12/26 06:20 編集

x_xさん インクリメントのスピードでどのくらいのペースで処理が進んでいるかが視覚的にわかればいいなと思っています。 プログレスバー自体はMarqueeです。
asus2

2018/12/26 06:23 編集

Zuishinさん string fileX, string fileYにはArrayに格納されている写真ファイルのパスが渡されてきていて、 撮影日・撮影日が無ければファイル更新日時をそれぞれ取得して比較しています。 比較するファイル数は2,3M程度のファイルが1000枚程度です。 不勉強で申し訳ないのですがLINQでは上記のどこからどこまでをカバーすることができるのか教えていただけないでしょうか。
Zuishin

2018/12/26 06:23

各要素についてキーとなる日時を一度だけ作成する仕様になっていますから、完全にカバーできると言えます。
ozwk

2018/12/26 06:49

単位時間あたりの比較回数を通知したところで それが速いのか遅いのかもわからないし、ソートが後どのぐらいで終わるのかもわからないので ソートに時間がかかるのであれば処理中かどうかだけ示せばいいと思うんですが。
guest

回答3

0

ベストアンサー

次のようにしてみてください。
もう進捗表示は要らないかもしれません。

C#

1array = array 2 .Select(a => new { Name = a, Time = GetFileCreateOrRenovationDateTime(a) }) 3 .OrderBy(a => a.Time) 4 .Select(a => a.Name) 5 .ToArray();

#追記

上記は配列を作り直しています。もともとの配列のインスタンスを変更してはいけない場合は次のようにしてください。

C#

1array2 = array 2 .Select(a => new { Name = a, Time = GetFileCreateOrRenovationDateTime(a) }) 3 .OrderBy(a => a.Time) 4 .Select(a => a.Name) 5 .ToArray(); 6Buffer.BlockCopy(array2, array, array2.Length);

#追記

もっと短くなりました。

C#

1array = array 2 .OrderBy(a => GetFileCreateOrRenovationDateTime(a)) 3 .ToArray();

投稿2018/12/26 06:28

編集2018/12/26 07:04
Zuishin

総合スコア28660

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

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

asus2

2018/12/26 06:52

自分で挑戦していたのですがなかなかうまく組み立てられずにいました…。 Zuishinさんが作成されたソースを入れてみたところ今までのソート処理はなんだったのかというくらい 素早く終了しました、とても助かりましたありがとうございます。 LINQにはまったく触れてこなかったのですがこれを機に勉強したいと思います。
guest

0

グローバル変数なり、適切なスコープの変数を用意して、ComparsionASC内でインクリメントすればいいのでは?
Sortを呼ぶ前に初期化してやれば、そのソートで呼び出された回数が分かるかと

投稿2018/12/26 05:47

YAmaGNZ

総合スコア10258

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

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

asus2

2018/12/26 06:04

すいません、目的を追記しました。 ソート処理中に表示されるProgressBarの下へ進捗表示のためにカウントを取りたいと考えています。 リアルタイムに何回通っているかを取得するのは難しいでしょうか
YAmaGNZ

2018/12/26 06:18 編集

表示側で100msなどの短いタイマー等でそのカウンタを参照してはどうでしょう? 何回通ったら完了とするかは知りませんが あー、ソート自体をUIスレッドで動かすと画面更新できませんね
guest

0

こんにちは。

目的がいまいちわかりませんが、ただ数値を取りたいだけならこれでいいのでは?

csharp

1public void Hoge(){ 2 common.Count = 0; 3 Array.Sort(Array, common.ComparsionASC); 4} 5 6 7//呼び出されたComparsion 8public int Count { get; set; } 9 10public int ComparsionASC(string fileX, string fileY) 11{ 12 this.Count++; 13 DateTime datetimeX = GetFileCreateOrRenovationDateTime(fileX); 14 DateTime datetimeY = GetFileCreateOrRenovationDateTime(fileY); 15 16 return DateTime.Compare(datetimeX, datetimeY); 17}

投稿2018/12/26 05:46

編集2018/12/26 05:48
tamoto

総合スコア4105

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

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

asus2

2018/12/26 06:01

すいません、目的を追記しました。 ソート処理中に表示されるProgressBarの下へ進捗表示のためにカウントを取りたいと考えています。
tamoto

2018/12/26 06:05

それだと、同期的な処理では完了するまで画面更新が働かないので、ソート処理を非同期実行した上でプログレスを逐一取りにいくなどしないといけないのでなかなか簡単ではないですね。 そのあたりの知識は大丈夫でしょうか?
asus2

2018/12/26 06:15

非同期処理ですね、使用したことがないので調べてみたいと思います。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問