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

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

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

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

Q&A

解決済

3回答

6992閲覧

C# 配列の中に含まれる日付をもとに順番を並び替える方法について

gohan1go

総合スコア18

C#

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

0グッド

0クリップ

投稿2019/04/23 04:55

編集2019/04/23 05:52

前提・実現したいこと

配列のSortに関する質問です。
名前に日付が含まれる数個のファイルを読み込み配列に格納。
ファイル名の日付を抽出しそれをもとにSortし日付の若い順にファイルを別のメソッドで読み込む。
<ファイル名例>
・aiueo20190505.xlsx
・kakiku20190706.xlsx
・sashisu20190122.xlsx

補足情報等必要でしたらおっしゃっていただければ幸いです。
どうぞよろしくお願いいたします。

現在の状況

以下のコードを試してみたのですが、思い通りの順番に並ばない状態です。

該当のソースコード

C#

1private void DoImportFiles(string[] xlsxfiles) 2 { 3 SortByDate comp = new SortByDate(); 4 Array.Sort(xlsxfiles, comp); 5 6 foreach (string xlsxfile in xlsxfiles) 7 { 8 // 1ファイルづつ処理する 9 DoImportFile(xlsxfile); 10 } 11 12 } 13 14public class SortByDate : IComparer 15 { 16 public int Compare(object x, object y) 17 { 18 string str1 = (string)x; 19 string str2 = (string)y; 20 DateTime date1; 21 DateTime date2; 22 23 Regex re = new Regex(@"[^0-9]"); 24 25 //数字以外を削除 26 str1 = re.Replace(str1, ""); 27 str1 = str1.Insert(4, "/"); 28 str1 = str1.Insert(7, "/"); 29 str2 = re.Replace(str2, ""); 30 str2 = str2.Insert(4, "/"); 31 str2 = str2.Insert(7, "/"); 32 33 //数字文字列を数値に変換 34 //num1 = int.Parse(str1); 35 //num2 = int.Parse(str2); 36 date1 = DateTime.Parse(str1); 37 date2 = DateTime.Parse(str2); 38 39 // return (date1 - date2).Days; 40 return date1.CompareTo(date2); 41 42 } 43 }

試したこと

ここのサイトを参考にIComparerを使用しSortしようとしてみました。
http://chunye.seesaa.net/article/423464142.html

補足

入力ミスそご指摘いただきまして、サンプルのファイル名を正しいものに変更しました。
読み込むファイル名の形式は
<文字列><8桁の数字>.xlsx
という順番の組み合わせです。

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

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

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

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

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

moredeep

2019/04/23 05:40

ファイル名例に201901220と1文字多いのがありますが、これは仕様ですか? 思い通りの順番に並ばないというのを、実際の入力、出力で示せますか?(こんな値を入力したとき、こうなってほしいが、こうなってしまう) Sort自体のやり方で詰まっているのか、Sort対象の値の抽出に詰まっているのか判断しかねます。
gohan1go

2019/04/23 05:48

失礼しました。ご指摘ありがとうございます。 サンプルのファイル名はこちらの入力ミスでした。 正しいものに更新させていただきました。
guest

回答3

0

ベストアンサー

LINQOrderByが真っ先に思い浮かびました。
ファイルの日付が8文字固定であればSubstringメソッドで抜き出してしまえば良いかと。

C#

1 private void DoImportFiles(string[] xlsxfiles) 2 { 3 foreach (string xlsxfile in xlsxfiles.OrderBy(v => v.Substring(v.Length - 8)) 4 { 5 // 1ファイルづつ処理する 6 DoImportFile(xlsxfile); 7 } 8 }

投稿2019/04/23 05:37

編集2019/04/23 07:37
BluOxy

総合スコア2663

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

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

gohan1go

2019/04/23 07:36

回答ありがとうございます。 aはxlsxfilesの中の一つの要素になるかと思うのですが、この場合だとどのようにしてaに当てはめるのでしょうか?
BluOxy

2019/04/23 07:37

typoです。vがxlsxfilesの中の一つの要素になるので、vに置き換えてください。
BluOxy

2019/04/23 07:43

xlsxfilesの中身について言及していませんでしたが、xlsxfilesに拡張子も含まれる場合は「後ろから12文字目の中から先頭8文字分」Substringするよう書き換えれば良いです。v.Substring(v.Length - 12,8)。
gohan1go

2019/04/23 08:14

ありがとうございます。無事意図したと通りにソートすることができました。 6ケタの数字を何とか日付に変換して。。。と考えず単に数値として利用するというところに気付けませんでした。 IComparerを考えていましたがLinqでこんなにシンプルに書くことができるんですね!
guest

0

ファイル名から数字列を取り出してそれをキーにソートすればいいんじゃないでしょうか

#別に日付と意識する必要もないでしょう

投稿2019/04/23 04:57

y_waiwai

総合スコア87774

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

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

gohan1go

2019/04/23 08:16

おっしゃる通りただ単に数値として考えれば簡単ですね! 何とか日付に変換して計算することにとらわれていました。 ご回答ありがとうございました!
guest

0

CharにIsDigit という静的メソッドがなかったですか?ファイル名を1文字ずつ検査して、これを通せば数字だけ取り出せますよね?
数字が6文字か8文字か、それ以外かで分けて、適切な場所にスラッシュを挿入すれば、DateTime型にパースできませんか?
元のファイル名と、そこから導き出された日付とのリンクが必要ですが、それでソートできますよね。

投稿2019/04/23 05:42

Q71

総合スコア995

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問