C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: 5つのDateTime変数から、直近のものを選び出す方法


(過去ログ 30 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■14298 / inTopicNo.1)  5つのDateTime変数から、直近のものを選び出す方法
  
□投稿者/ tucchi (5回)-(2008/02/14(Thu) 21:02:49)

分類:[C#] 

開発環境:VS2003 C#

こんにちは。tucchiと申します。

5つの(未来の時間が入った)DateTime型変数
・operationTimeA
・operationTimeB
・operationTimeC
・operationTimeD
・operationTimeE
があり、その中から直近の時間のものを選び出す
プログラムを作成しようと思っています。
(直近の時間で、同じ時刻のものが複数あれば、それを列挙したいです)

ただ、その方法で悩んでいます。
すみませんが、なにかヒントをいただけませんでしょうか?
引用返信 編集キー/
■14299 / inTopicNo.2)  Re[1]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ よねKEN (120回)-(2008/02/14(Thu) 21:14:21)
昇順に並び替えて、最小値となる日時群が答えですね。
この中のどの辺りが不明でしょうか?

C#で大小比較の演算子をDateTimeにそのまま適用できるのかどうか押さえてませんが、
比較演算子が使えるならそれで、使えないならDateTime構造体の以下のメソッドで比較できますね。

DateTime.CompareTo (DateTime)

並べ替えのロジックはよくあるものですから、「ソート アルゴリズム」で調べるとよいでしょう。
また、.NET Frameworkの機能としてもいくつかのクラスにSortメソッドがありますので、
MSDNで検索してみてください。


引用返信 編集キー/
■14300 / inTopicNo.3)  Re[2]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ tucchi (6回)-(2008/02/14(Thu) 21:39:54)
No14299 (よねKEN さん) に返信
回答ありがとうございます。
言葉足らずですみませんでした。

以下のようなコードを書いてみました。

---コード---
	DateTime operationTimeA = new DateTime(2008,2,1,15,0,0);
	DateTime operationTimeB = new DateTime(2008,2,2,10,0,0);
	DateTime operationTimeC = new DateTime(2008,2,1,8,0,0);
	DateTime operationTimeD = new DateTime(2008,2,1,10,0,0);
	DateTime operationTimeE = new DateTime(2008,2,2,8,0,0);

	ArrayList array = new ArrayList();
	array.Add(operationTimeA);
	array.Add(operationTimeB);
	array.Add(operationTimeC);
	array.Add(operationTimeD);
	array.Add(operationTimeE);

	array.Sort();

	foreach (DateTime dt in array)
	{
		Console.WriteLine(dt.ToString());
	}

---表示結果---
2008/02/01 8:00:00
2008/02/01 10:00:00
2008/02/01 15:00:00
2008/02/02 8:00:00
2008/02/02 10:00:00

これだと、ちゃんと昇順で変わっているのですが、
どの変数が1位になったのかが、わかりません。

先ほどの質問ではその部分がぬけていましたが、
どの変数が1位になったのかの情報も含めて、ソートした情報を取得したかったのです。

何かいい方法はありますでしょうか?

引用返信 編集キー/
■14301 / inTopicNo.4)  Re[3]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ επιστημη (828回)-(2008/02/14(Thu) 21:50:05)
επιστημη さんの Web サイト
通し番号も一緒に並び変えたらええですねー

using System;
using System.Collections;

public class Program {
  public static void Main() {

    DateTime operationTimeA = new DateTime(2008,2,1,15,0,0);
    DateTime operationTimeB = new DateTime(2008,2,2,10,0,0);
    DateTime operationTimeC = new DateTime(2008,2,1,8,0,0);
    DateTime operationTimeD = new DateTime(2008,2,1,10,0,0);
    DateTime operationTimeE = new DateTime(2008,2,2,8,0,0);

    SortedList list = new SortedList();
    list.Add(operationTimeA,0);
    list.Add(operationTimeB,1);
    list.Add(operationTimeC,2);
    list.Add(operationTimeD,3);
    list.Add(operationTimeE,4);

    foreach ( DictionaryEntry de in list) {
        Console.WriteLine("[{0}] {1}", de.Value, de.Key);
    }
  }
}

引用返信 編集キー/
■14302 / inTopicNo.5)  Re[3]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ よねKEN (121回)-(2008/02/14(Thu) 21:53:11)
そこまでできてるなら、そう書いてくださいね。

> 先ほどの質問ではその部分がぬけていましたが、
> どの変数が1位になったのかの情報も含めて、ソートした情報を取得したかったのです。

ぱっと思いつく方法はあるのですが、その前に、
「どの変数が1位になったのかの情報」はどのように取得できればいいのでしょうか?
例えば、"operationTimeA"というような識別用の名前で判定できればいいのでしょうか?

その後、その情報をどう利用するのかといった背景がわからないので、
どういった形のアウトプットを求めているのかわかりませんので、
具体例など挙げてみてください。

引用返信 編集キー/
■14303 / inTopicNo.6)  Re[4]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ 魔界の仮面弁士 (623回)-(2008/02/14(Thu) 22:11:44)
No14301 (επιστημη さん) に返信
> 通し番号も一緒に並び変えたらええですねー

これだと、
>>> 同じ時刻のものが複数あれば、それを列挙したいです
のように、同じ時刻があった時に失敗する予感。


どのように列挙したいのか分からなかったのだけれど、これでどうだろう?

Hashtable rawList = new Hashtable();
rawList.Add("operationTimeA", operationTimeA);
rawList.Add("operationTimeB", operationTimeB);
rawList.Add("operationTimeC", operationTimeC);
rawList.Add("operationTimeD", operationTimeD);
rawList.Add("operationTimeE", operationTimeE);

SortedList sortedList = new SortedList();
foreach (DictionaryEntry item in rawList)
{
    StringCollection keys;
    if (sortedList.ContainsKey(item.Value))
    {
        keys = (StringCollection)sortedList[item.Value];
    }
    else
    {
        keys = new StringCollection();
        sortedList.Add(item.Value, keys);
    }
    keys.Add((string)item.Key);
}

int rank = 1;
foreach (DictionaryEntry item in sortedList)
{
    DateTime dt = (DateTime)item.Key;
    StringCollection names = (StringCollection)item.Value;
    Console.WriteLine("{0}位: {1:yyyy/MM/dd HH:mm:ss}", rank, dt);
    foreach (string name in names)
    {
        Console.WriteLine("  変数名:{0}", name);
    }
    rank += names.Count;
}

引用返信 編集キー/
■14304 / inTopicNo.7)  Re[4]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ tucchi (7回)-(2008/02/14(Thu) 22:13:34)
No14302 (よねKEN さん) に返信
> そこまでできてるなら、そう書いてくださいね。
失礼しました。すみません。

> ぱっと思いつく方法はあるのですが、その前に、
> 「どの変数が1位になったのかの情報」はどのように取得できればいいのでしょうか?
> 例えば、"operationTimeA"というような識別用の名前で判定できればいいのでしょうか?
そのへんが、どうやったらいいのか、整理できていません。
なので、作ろうとしているものの具体例を挙げさせてください。

*Windowsサービスで実装
*5つの処理がある
 ・ファイルを読み込んで、DBテーブルへレコード挿入
 ・DBからデータを取得して、CSV出力
 ・DBからデータを取得して、メール送信
 ・etc...
*5つの処理は1日に1回行われる仕様になっていて、それぞれ何時に行うかは設定ファイルなどで決められている。(例:opeA=1300 ←13時に動作)

で、現在作ったのは、
設定ファイルから動作時刻を取得し、それぞれの動作時刻を以下の例のように決定。
(例:処理Aの動作時刻は、"13:00"の設定。現在時刻が"2008/2/14 12:00"の場合、次の処理A動作時刻は、翌日の"2008/2/15 13:00"となる)
それぞれ、
DateTime operationTimeA;
DateTime operationTimeB;
DateTime operationTimeC;
DateTime operationTimeD;
DateTime operationTimeE;
に代入する・・・というところまでです。

そこで次に、直近に動作しなければならない時刻は何時で、それはどの処理なのか?を取得しようと思ったところで詰まっていました。

アドバイスいただけますでしょうか?
引用返信 編集キー/
■14305 / inTopicNo.8)  Re[5]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ tucchi (8回)-(2008/02/14(Thu) 22:16:54)
No14301 (επιστημη さん) に返信
No14303 (魔界の仮面弁士 さん) に返信

回答ありがとうございます。
ちょっとすぐには内容を理解できないのですが、テストしたり調べながら参考とさせていただきます。

さしあたって、お礼だけ書き込ませていただきます。
つい先ほど、作成しようとしている物の具体例も書き込んだところでしたので、「解決済み」までもうしばらく時間をかけさせてください。
よろしくお願いします。
引用返信 編集キー/
■14310 / inTopicNo.9)  Re[5]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ 魔界の仮面弁士 (624回)-(2008/02/14(Thu) 22:42:46)
2008/02/14(Thu) 22:46:20 編集(投稿者)

No14304 (tucchi さん) に返信
> *5つの処理がある
>  ・ファイルを読み込んで、DBテーブルへレコード挿入
>  ・DBからデータを取得して、CSV出力
>  ・DBからデータを取得して、メール送信
>  ・etc...
> *5つの処理は1日に1回行われる仕様になっていて、それぞれ何時に行うかは設定ファイルなどで決められている。

いっそ、それらを DataTable に放り込んでおく…というのはどうでしょう?
http://www.vb-user.net/junk/replySamples/2008.02.14.22.38/14298.zip

DataTable なら、DataView 経由での並び替えや、条件絞り込みなども可能ですし。
引用返信 編集キー/
■14311 / inTopicNo.10)  Re[5]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ よねKEN (122回)-(2008/02/14(Thu) 22:50:52)
2008/02/14(Thu) 22:51:42 編集(投稿者)
> そこで次に、直近に動作しなければならない時刻は何時で、それはどの処理なのか?
> を取得しようと思ったところで詰まっていました。

ということはどの処理のなのか?の判定用の値はIDでも名前でもよさそうですね。

C#だと書くのに時間がかかるのでVBのコードで申し訳ないのですが、
例えば、以下のようなクラスを作ってはどうでしょうか。
このクラスのようなのを用意すれば、tucchiさんの元のソースでDateTime型をAddしているのを
Task型に変えればOKです。
・Nameはその処理の名前
・Priorityは同時刻の場合のソート順を決定する優先順位

'※ 実行してません。のでバグが普通にありそう。
Public Class Task
    Implements IComparable
    Public OperationDateTime As DateTime
    Public Name As String
    Public Priority As Integer

    Public Sub New(ByVal OperationDateTime As DateTime, _
                   ByVal Name As String, _
                   ByVal Priority As Integer)

          Me.OperationDateTime = OperationDateTime
          Me.Name  = Name 
          Me.Priority  = Priority
    End Sub

    Public Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
        If TypeOf obj Is Task Then
            Dim target As Task= DirectCast(obj, Task)
            Dim ret As Integer = OperationDateTime.CompareTo(target.OperationDateTime)

            If ret = 0 Then
               Return Priority.CompareTo(target.Priority)
            End If
            Return ret
        End If

        Throw New ArgumentException("比較対象がTaskオブジェクトではありません。")
    End Function
End Class

※Array.SortやSortedListが安定したソートかどうかMSDNで記述を見つけられなかったので、
 明示的に優先順位を指定できるようにしてみました。

引用返信 編集キー/
■14317 / inTopicNo.11)  Re[6]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ tucchi (9回)-(2008/02/15(Fri) 00:37:31)
みなさん、ありがとうございます!

すごいですね。
みなさん、短時間でサンプルを含めた詳細な回答をいただいて、
とてもありがたくて感激です。

いろいろ試してみて、参考とさせていただきます。

また、結果を報告させていただきますね。


解決済み
引用返信 編集キー/
■14324 / inTopicNo.12)  Re[7]: 5つのDateTime変数から、直近のものを選び出す方法
□投稿者/ Jitta on the way (30回)-(2008/02/15(Fri) 07:56:00)
ここに出された質問は解決しても、作らなければならないものの仕様は満足していない予感。


検査を行う間隔と、設定される時間の単位によっては、処理されないデータがあるような気がする。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -