2017-07-30 70 views
0

我通過使用計時器並將它們添加到列表框或datagridview中獲取數據。我需要得到每個數十年的價值,例如; 10,20,30,40,50..如何在c#中獲得每十年最接近的價值?

但並不總是數據來自我想要的。有一個示例數據來了; 10.15 14.45 19.65 22.18 27.89 30.15 31.15 37.46 42.01 ...

根據上面的數據,我想列出這些數據在我的代碼;

10.15 as 10 19.65 as 20 30.15 as 30 42.01 as 40 ...

正如你看到的,我不想錯過任何的十年。 在我的代碼label1.text represents velocity,label2.Text represents timewatch is a stopwatch首先,我正在收集數據給lisboxes,然後將它們帶到datagirview.Here是我的代碼;

private void timer2_Tick(object sender, EventArgs e) 
{ 
    watch.Start(); 
    var time = watch.Elapsed.TotalSeconds; 
    if (Math.Round(Convert.ToDouble(label1.Text)) % 10 == 0) 
    { 
     listBoxTime.Items.Add(label2.Text); 
     listBoxVelocity.Items.Add(label1.Text); 
     p = dataGridView1.Rows.Add(); 
     for (int i = 1; i < listBoxTime.Items.Count; i++) 
     { 
      dataGridView1.Rows[p].Cells[0].Value = listBoxVelocity.Items[i].ToString(); 
      dataGridView1.Rows[p].Cells[1].Value = listBoxTime.Items[i].ToString(); 

     } 
    } 
} 

正如我之前所說,我應該怎麼做才能獲得每個十年最接近的數據而不會錯過任何十年。

+0

我預計10.5,因爲它比11.5更接近10。 – Quanthema

+0

你期望15回合到什麼程度? 25呢? – mjwills

+0

會發生這種情況有十年沒有了嗎? – Ecstabis

回答

0

您可以將數字除以十,然後將它們四捨五入,再乘以十。檢查兩者之間的差異,並將其與以前的比較。

更新(以前的答案刪除) 現在剛開最低。可能不是最優雅/通用的方式,但它應該工作。 UPDATE2: 替換C#代碼6

class Numbers { 
    public int Rounded { get; set; } 
    public double Number { get; set; } 
    public double Difference 
    { 
     get { return Math.Abs(Rounded - Number); } 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var numbers = new [] {10.15, 14.45, 19.65, 22.18, 27.89, 30.15, 31.15, 37.46, 42.01}; 
     var decades = new List<Numbers>(); 

     foreach (var number in numbers) 
     { 
      var rounded = (int)Math.Round(number/10, MidpointRounding.AwayFromZero) * 10; 
      var found = decades.FirstOrDefault(x => x.Rounded == rounded); 

      if (found == null) 
       decades.Add(new Numbers { Rounded = rounded, Number = number }); 
      else if (found.Difference > Math.Abs(rounded - number)) 
       found.Number = number; 
     } 

     foreach (var number in decades) 
      Console.WriteLine($"{number.Number} as {number.Rounded}"); 

     Console.ReadKey(); 
    } 
} 

結果:

10.15 as 10 
19.65 as 20 
30.15 as 30 
42.01 as 40 

,如果你想堅持到數字,沒有獲得晉級,我不知道,但這不應該太難添加。

變化

public double Difference => MathAbs(Rounded - Number); 

C#6替代-1

public double Difference() { 
    return Math.Abs(Rounded - Number); 
} 

C#6替代-2

public double Difference { 
    { 
     get { return Math.Abs(Rounded - Number); } 
    } 
} 
+0

我的猜測是他期待一個只包含最接近十年的值的新數組。在他的例子中,由於指出中點舍入,它會給出[10.15,19.65,30.15,42.01]' – Ecstabis

+0

@mjwills。我已經更新了答案。 – nGAGE

+0

@nGAGE感謝您的回覆,但在他的解決方案中,如果有一個數字爲11,12,13,14,則需要將它們全部設置爲10.但是我只想得到最接近的一個,所以對此有11個。 – Quanthema

0

的FOLL欠款解決方案顯示了一種可能的方法要使用此功能,請務必將this Nuget package添加到您的項目中。

代碼基本上舍入到最接近的十年中,然後選擇其爲最接近(即最小的差)項作爲例子。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using MoreLinq; 

class Program 
{ 
    private static IEnumerable<DecadeAndClosest> GroupByDecade(double[] input) 
    { 
     var rounded = input.Select(z => new 
     { 
      original = z, 
      rounded = Math.Round(z/10, MidpointRounding.AwayFromZero) * 10 
     }); 
     var roundedWithDifference = 
      rounded.Select(z => new { z.original, z.rounded, difference = Math.Abs(z.original - z.rounded) }); 
     var finalResults = roundedWithDifference.GroupBy(z => z.rounded) 
      .Select(z => new DecadeAndClosest() { Decade = z.Key, Example = z.MinBy(Y => Y.difference).original }); 
     return finalResults; 
    } 

    public class DecadeAndClosest 
    { 
     public double Decade { get; set; } 
     public double Example { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     var input = new[] 
     { 
      10.15, 
      14.45, 
      19.65, 
      22.18, 
      27.89, 
      30.15, 
      31.15, 
      37.46, 
      42.01 
     }; 

     var finalResults = GroupByDecade(input); 

     foreach (var indiv in finalResults) 
     { 
      Console.WriteLine(string.Format("{0} - {1}", indiv.Decade, indiv.Example)); 
     } 

     Console.ReadLine(); 
    } 
} 
+0

感謝您的回覆。它在Windows窗體應用程序中是否也有效.. – Quanthema

+0

是的,它可以在任何地方工作。我包含完整的控制檯應用程序代碼供您測試。您可以將「GroupByDecade」和「DecadeAndClosest」複製並粘貼到任何類型的項目中(只要它具有我提到的Nuget包)。 – mjwills

+0

非常感謝您的回覆,但代碼在此部分提供了一個錯誤'Example = z.MinBy(Y => Y.difference).original'。此外,我的代碼與計時器滴答作用,我不能讓你的代碼施加定時器間隔工作。 – Quanthema