C#ListView-搜索精确的时间值(HH:mm:ss)或最接近的值

本文关键字:mm ss 最接近 搜索 时间 C#ListView- HH | 更新日期: 2023-09-27 18:03:52

我正在寻找一种方法,在列表视图中搜索一个精确的值或列表中最接近它的值。

这些值都是时间值("HH:mm:ss"(。我还没有写很多代码,但我会把我到目前为止的代码发布出来。

下面的方法引用了一个名为lstData的ListView,它保存时间值。索引被传递给选择特定时间的方法。我想做的是在lstData中的这个位置获取值,并在另一个名为lstReport的ListView中找到相同的值或最接近的值。lstReport不一定有相同的时间值,而是有很多相似的时间值和相同的格式,因此我希望选择lstRepot中最接近的值。

private void SelectTime(int val)
    {
        try
        {
            CurrentIndex = val;
            lstData.Items[CurrentIndex].Selected = true;
            lstData.EnsureVisible(CurrentIndex);
            String text = lstData.Items[CurrentIndex].Text;
            MessageBox.Show("Time Selected: " + text);

            // This is where I want to search lstReport for the closest time value 
            // to lstData.Items[CurrentIndex] value
            this.Refresh();
        }
        catch
        {
        }
    }

如果我没有很好地解释这一点,我很抱歉,如果是这样的话,请留下评论,我会尽量让它更清楚。感谢

编辑

// get the selected item from lstData
            String text = lstData.Items[CurrentIndex].Text;
            // parse the value
            long SelectedDate = DateTime.Parse(text).Ticks;
            //  extract the listview items into a list of strings
            List<string> list = lstData.Items.Cast<ListViewItem>().Select(item => item.Text).ToList();
            //By converting the values to Long, we can get the closest value using Math.Abs.
            string closest = list.Aggregate((x, y) => Math.Abs(DateTime.Parse(x).Ticks - SelectedDate) < Math.Abs(DateTime.Parse(y).Ticks - SelectedDate) ? x : y);

C#ListView-搜索精确的时间值(HH:mm:ss)或最接近的值

您可以使用LINQ通过对时间的绝对差进行排序来获得最接近的值。假设您有两个类型为DateTime的列表lstReportlstData。然后像一样

private void SelectTime(int val)
{
    try
    {
        CurrentIndex = val;
        lstData.Items[CurrentIndex].Selected = true;
        lstData.EnsureVisible(CurrentIndex);
        String text = lstData.Items[CurrentIndex].Text;
        MessageBox.Show("Time Selected: " + text);
        //Get the closest DateTime to the Current item of lstData
        DateTime MinimumDifferenceItem = lstReport.Items.Cast<DateTime>().OrderBy(Dt => Math.Abs((Dt - (DateTime)lstData.Items[CurrentIndex]).Milliseconds)).First();
        this.Refresh();
    }
    catch { }
}

别忘了添加

using System.Linq;

到您的文件。

编辑:

如果您的列表仅包含字符串,则可以通过添加类似于Convert.ToDateTime的来修改查询

String MinimumDifferenceItem = lstReport.Items.Cast<string>().OrderBy(Ts => Math.Abs((Convert.ToDateTime(Ts) - Convert.ToDateTime(lstData.Items[CurrentIndex])).Milliseconds)).First();

您应该在列表视图中使用TimeSpan而不是string。否则,您将不得不进行不必要的转换。

从第一个列表视图中获取时间后,循环浏览第二个列表视图并计算两者之间的差异,跟踪第二个视图中的索引和单独变量中的差异。当您在第二个列表中找到更接近的时间时,请更新索引和差异变量。

当你完成后,你应该从第二个列表中获得最接近第一个列表的时间。列表视图应自动调用TimeSpan上的ToString(),以便显示良好。

   //Example List containing the time values
        List<string> dates = new List<string>();
        dates.Add("00:00:01");
        dates.Add("00:00:02");
        dates.Add("00:00:03");
        dates.Add("00:00:09");
        dates.Add("00:00:05");
        dates.Add("00:00:07");
        //The time value selected in the listview
        long SelectedDate = DateTime.Parse("00:00:04").Ticks;
        //By converting the values to Long, we can get the closest value using Math.Abs.
        string closest = dates.Aggregate((x, y) => Math.Abs(DateTime.Parse(x).Ticks - SelectedDate) < Math.Abs(DateTime.Parse(y).Ticks - SelectedDate) ? x : y);

更新匹配您的请求:

您提到您有两个listview lstData和lstReport。您从lstData中选择一个值,并希望输出lstReport中包含的最接近的值。只需尝试以下步骤:

  1. 将所选值存储在字符串变量中
    String text = lstData.Items[CurrentIndex].Text;
  2. 将其转换为长类型:
    long selectedvalue = DateTime.Parse(text).Ticks;
  3. 将lsReport中的项强制转换为字符串列表:
    List<string> valuelist = lstReport.Items.Cast<ListViewItem>().Select(item => item.Text) .ToList();
  4. 将valuelist与selected值进行比较以获得最接近的值:
    string closest = valuelist.Aggregate((x, y) => Math.Abs(DateTime.Parse(x).Ticks - selectedvalue) < Math.Abs(DateTime.Parse(y).Ticks - selectedvalue) ? x : y);