2017-09-29 42 views
0

現在のプロジェクトは現在進行中ですが、問題がありました。プロジェクトが何をする必要があるのですか:リストの最大値と最小値

特定の日付の範囲から最高と最低温度を探します。日付の範囲は、ユーザによって入力される。

だから、私は(両方の新しい形態の)項目を入力し、最大値と最小値を求めるためのメインメニューとしてフォームを作ります。私はアイテム格納するためのクラスも行います。最初の形式で

public class TempDate 
{ 
    public double Temp { get; set; } 

    public DateTime Date { get; set; } 
} 

を、ちょうどFormAddDataそれを呼び出す、ここからのアイテムは、テキストボックスを使用してリストに格納され、ここでのコードがあります:

private void buttonSubmit_Click(object sender, EventArgs e) 
    { 
     FormMenu formMenu = (FormMenu)this.Owner; 

     DateTime date = dateTimePickerDate.Value.Date; 
     double temp = double.Parse(textBoxTemp.Text); 

     TempDate tempDate = new TempDate(); 

     tempDate.Date = date; 
     tempDate.Temp = temp; 

     formMenu.listOfTempDate.Add(tempDate); 
     listBoxInfo.Items.Add(date + "\t" + temp + "°C"); 
    } 

FormMaxMinRangeという2番目の形式です。このフォームでは、開始日には最初の1つ、終了日には2つ目のDateTimePickerを使用します。ここからは、開始日と終了日から使用した範囲のすべての項目を選択するボタンを作成する必要があります。問題は、最小値がの範囲内で選択されなかったが、

public partial class FormMenu : Form 
{ 
    public List<TempDate> listOfTempDate = new List<TempDate>(); 

    public FormMenu() 
    { 
     InitializeComponent(); 
    } 

    private void fromCertainRangeToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
     FormMaxMinRange formMaxMinRange = new FormMaxMinRange(); 
     formMaxMinRange.Owner = this; 
     formMaxMinRange.ShowDialog(); 
    } 
} 

しかし:

private void buttonMaxMin_Click(object sender, EventArgs e) 
    { 
     FormMenu formMenu = (FormMenu)this.Owner; 

     DateTime start = dateTimePickerStart.Value.Date; 
     DateTime end = dateTimePickerEnd.Value.Date; 
     int highest = 0; 
     double max = formMenu.listOfTempDate[0].Temp; 
     int lowest = 0; 
     double min = formMenu.listOfTempDate[0].Temp; 

     for (int i = 1; i < formMenu.listOfTempDate.Count; i++) 
     { 
      if (formMenu.listOfTempDate[i].Date >= start 
       && formMenu.listOfTempDate[i].Date <= end) 
      { 
       if (formMenu.listOfTempDate[i].Temp > max) 
       { 
        highest = i; 
        max = formMenu.listOfTempDate[i].Temp; 
       } 

       if (formMenu.listOfTempDate[i].Temp < min) 
       { 
        lowest = i; 
        min = formMenu.listOfTempDate[i].Temp; 
       } 
      } 
     } 
     listBoxMaxMin.Items.Add(""); 
     listBoxMaxMin.Items.Add("Lowest temp: " + min + ", on " + formMenu.listOfTempDate[lowest].Date); 
     listBoxMaxMin.Items.Add("Highest temp: " + max + ", on " + formMenu.listOfTempDate[highest].Date); 
    } 

ここでは(リストを含む)に、私はクラスを宣言したメインフォームだ:ここに私のコードです選択。また、最大値と最小値がリストボックスに表示されます。長くて奇妙な質問には申し訳ありません。私は誰かが私のプロジェクトを完了するためにこの質問で私が何を意味するのか理解することができれば幸いですありがとうございました。

答えて

2

を提出あなたは.csの上にusing System.Linqを追加することを忘れないでください。 Linqを使用して縮小リスト(Start/Enddate)を選択し、Tempで並べ替えることができます。これで、最初の(最小)オブジェクトと最後の(最大)オブジェクトを簡単に選択できます。 (今日は)

List<TempDate> loTempDateList = new List<TempDate>() 
{ 
    new TempDate() {Date = DateTime.Now.AddDays(-10), Temp = 10.01 }, 
    new TempDate() {Date = DateTime.Now.AddDays(-5), Temp = 20.01 }, 
    new TempDate() {Date = DateTime.Now.AddDays(-3), Temp = 30.01 }, 
    new TempDate() {Date = DateTime.Now, Temp = 40.01 } 
}; 
DateTime ldStart = DateTime.Now.AddDays(-6); 
DateTime ldEnd = DateTime.Now.AddDays(-1); 

var loDateList = loTempDateList.Where(item => item.Date <= ldEnd && item.Date >= ldStart) 
    .OrderBy(item => item.Temp); 

TempDate loMin = loDateList.First(); 
TempDate loMax = loDateList.Last(); 

Console.WriteLine("{0}: {1} with max temp", loMax.Date, loMax.Temp); 
Console.WriteLine("{0}: {1} with min temp", loMin.Date, loMin.Temp); 

出力:(あなたの変数名を持つ)

9/26/2017 3:17:09 PM: 30.01 with max temp 
9/24/2017 3:17:09 PM: 20.01 with min temp 

更新:あなたのフォームでDateTime end = dateTimePickerEnd.Value.Date;

コピー本を

var loDateList = listOfTempDate.Where(item => item.Date <= end && item.Date >= start) 
    .OrderBy(item => item.Temp); 

TempDate loMin = loDateList.FirstOrDefault(); 
TempDate loMax = loDateList.LastOrDefault(); 

if (loMin != null && loMax != null) 
{ 
    listBoxMaxMin.Items.Add(""); 
    listBoxMaxMin.Items.Add("Lowest temp: " + loMin.Temp + ", on " + loMin.Date); 
    listBoxMaxMin.Items.Add("Highest temp: " + loMax.Temp + ", on " + loMax.Date); 
} 
+0

アイテムをコードに直接保存しましたか? –

+1

これはあなたがそれを行う方法の単なる例です。 'loTempDateList'はあなたの' formMenu.listOfTempDate'で、 'ldStart、ldEnd'は' start、end'です – PinBack

+0

textBoxを使って日付と時刻を入力するとどうなりますか? –

1

Linq MaxMinの方法を使用することをお勧めします。

// filter out only the dates in the range you need 
var items = formMenu.listOfTempDateWhere(
    item => ((TempDate)item).Date >= start && ((TempDate)item).Date <= end 
); 

// get the maximum value 
var max = items.Max(item => item.Temp); 
// get the minimum value 
var min = items.Min(item => item.Temp); 

はちょうどこのコードスニペットを参照してください


try this online

+0

を - OPは私が – PaulF

+0

これらの方法を理解するものから、日付範囲で最大/最小を望んでいます型がComparableを実装している場合にのみ機能します:https://msdn.microsoft.com/en-us/library/bb352408(v=vs.110).aspx – AaronLS

+0

@PaulFはい、最初は質問を理解できませんでした。それを指摘していただきありがとうございます。 –

0

あなたは「ドン場合LINQのアプローチのように(私はLINQを使用しない、いくつかの、おそらく無効な理由、私はそれが悪だと思う)、あなたca n Listクラスをオーバーライドし、独自のメソッドで拡張します。

public class TempDataList<T> : List<TempData> 
{ 
    public TempDataList() : base() 
    { 
    } 

    public TempDataList(IEnumerable<TempData> collection) : base(collection) 
    { 
    } 

    public TempData GetMaxTemp(DateTime startDate, DateTime endDate) 
    { 
     TempData highestTempData = null; 
     for (int i = 0; i < this.Count; i++) 
     { 
      if (this[i].Date >= startDate && this[i].Date <= endDate) 
      { 
       if (highestTempData == null || this[i].Temp > highestTempData.Temp) 
       { 
        highestTempData = this[i]; 
       } 
      } 
     } 
     return highestTempData; 
    } 

    public TempData GetMinTemp(DateTime startDate, DateTime endDate) 
    { 
     TempData lowestTempData = null; 
     for (int i = 0; i < this.Count; i++) 
     { 
      if (this[i].Date >= startDate && this[i].Date <= endDate) 
      { 
       if (lowestTempData == null || this[i].Temp < lowestTempData.Temp) 
       { 
        lowestTempData = this[i]; 
       } 
      } 
     } 
     return lowestTempData; 
    } 
} 

と拡張リストを記入し、メソッドを呼び出します。これは、すべての項目の最大&最小を見つけるだろう

TempDataList<TempData> tempDataList = new TempDataList<TempData>(); 
tempDataList.Add(new TempData(10, DateTime.UtcNow)); 
tempDataList.Add(new TempData(20, DateTime.UtcNow)); 
tempDataList.Add(new TempData(15, DateTime.MinValue)); 
tempDataList.Add(new TempData(25, DateTime.MaxValue)); 

Console.WriteLine(tempDataList.GetMaxTemp(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1)).Temp); 
Console.WriteLine(tempDataList.GetMinTemp(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1)).Temp); 
関連する問題