如何在c#中获得每十年最接近的价值?

问题描述:

我通过使用计时器并将它们添加到列表框或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

您可以将数字除以十,然后将它们四舍五入,再乘以十。检查两者之间的差异,并将其与以前的比较。

更新(以前的答案删除) 现在刚开最低。可能不是最优雅/通用的方式,但它应该工作。 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

的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