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

时间:2016-08-25 12:27:23

标签: c# list listview arraylist listviewitem

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

值是所有时间值(“HH:mm:ss”)。我还没有编写很多代码,但我会发布到目前为止的内容。

以下方法引用名为lstData的ListView,它包含时间值。索引将传递给选择特定时间的方法。 我想要做的是获取lstData中此位置的值,并在另一个名为lstReport的ListView中找到相同的值或最接近的值。报告不一定具有相同的时间值,而是具有相同的格式,因此我希望选择lstReport中最接近的值。

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);

3 个答案:

答案 0 :(得分:2)

您可以使用LINQ通过排序时间的绝对差来获得最接近的值。假设您有lstReport类型的lstDataDateTime两个列表。然后就像

一样
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();

答案 1 :(得分:0)

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

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

完成后,您应该从第二个列表中得到的时间最接近第一个列表中的时间。列表视图应自动在TimeSpan上调用ToString(),以便它显示正常。

答案 2 :(得分:0)

   //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与selectedvalue进行比较以获得最接近的值:
    string closest = valuelist.Aggregate((x, y) => Math.Abs(DateTime.Parse(x).Ticks - selectedvalue) < Math.Abs(DateTime.Parse(y).Ticks - selectedvalue) ? x : y);