2013-02-11 2 views
0

Доброго утра, у меня есть два списка, мне нужно объединить вместе и создать таблицу данных из, я получил следующий блок кода:LINQ слияние двух списков и группировка по отметкам времени

private static DataTable GetDataTable(IList<DataValue> listOneDataValues, 
              IList<DataValue> listTwoDataValues) 
     { 
     var dataTable = new DataTable(); 
     dataTable.Columns.Add("ColumnFromListOne"); 
     dataTable.Columns.Add("ColumnFromListTwo"); 
     dataTable.Columns.Add("TimeStamp"); 

     //Group the lists together 
     var query = (from listOne in listOneDataValues 
         from listTwo in listTwoDataValues 
         let columnFromListOne= listOne.DoubleValue 
         let columnFromListTwo= listTwo.DoubleValue 
         let timestamp = listOne.TimeStamp 
         where listOne.TimeStamp == listTwo.TimeStamp 
         select new {ColumnFromListTwo = columnFromListOne, ColumnFromListOne = columnFromListTwo, Timestamp = timestamp}); 


     foreach(var q in query) 
      dataTable.Rows.Add(q.ColumnFromListOne, q.ColumnFromListTwo, q.TimeStamp); 

     return dataTable; 
     } 

Проблема состоит в том, что два списка содержат отметки времени, которые отключены на несколько секунд, и они не выравниваются вообще, поэтому мой конечный результат заканчивается одной или нулевой записью в datatable, хотя каждый список содержит более 200 записей. Я очень плохо отношусь к LINQ и буду признателен за правильное направление. Я думаю, мне нужно интерполировать временные метки перед группировкой, но я хотел бы узнать, как лучше всего сделать что-то подобное.

+0

Как вы хотите обрабатывать временные метки, которые вне на несколько секунд? Они * отличаются друг от друга, поэтому их следует рассматривать как разные. Вы можете округлить или усечь до ближайшей минуты, но что, если временные метки оседлают эту линию? Вы можете найти расстояние между ними, но если у вас много событий, вы получите перекрытие. – Bobson

+0

Самый низкий уровень детализации - каждые 5 минут. Мне нужно округлить вверх или вниз до ближайших 5 минут, я думаю. – Gallen

ответ

2

Вы должны решить, что соответствующий порог для вызова два временные отметки «равны» - зная, что слишком большой порог даст вам ложные срабатывания, а слишком маленький порог будет препятствовать присоединению некоторых записей.

Оттуда просто изменить свой запрос на

 int threshold = 5; 
    //Group the lists together 
    var query = (from listOne in listOneDataValues 
        from listTwo in listTwoDataValues 
        where Math.Abs(
            (listOne.TimeStamp - listTwo.TimeStamp) 
            .TotalSeconds 
           ) <= threshold 
        select new { 
           ColumnFromListTwo = listTwo.DoubleValue, 
           ColumnFromListOne = listOne.DoubleValue, 
           Timestamp = listOne.TimeStamp 
          }); 
+0

Оба являются хорошими ответами, но для вас это будет за полноту. – Gallen

4

Вы можете изменить where заявления

where Math.Abs((listOne.TimeStamp - listTwo.TimeStamp).TotalSeconds) < 5

Это будет рассматривать два раза отличающийся на 5 секунд, как «то же»

+1

Я бы избегал здесь магического номера. Создайте epsilon или пороговую переменную и убедитесь, что вы проводите некоторое тестирование на основе данных, чтобы определить, что такое соответствующее значение. Разные могут также быть в миллисекундах, а не секундах. – Servy

Смежные вопросы