|
|
@@ -185,11 +185,42 @@ public class Analytics
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- ...
|
|
|
+
|
|
|
+ return DateTimeWithCounterList
|
|
|
+ .OrderByDescending(item => item.Counter)
|
|
|
+ .ThenBy(item => item.DateTimeProp)
|
|
|
+ .Select(item => item.DateTimeProp)
|
|
|
+ .ToList();
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
+Для вычисления начала месяца мы использовали один из конструкторов класса **DateTime(year, month, day, hour, minutes, seconds)**, где год и месяц берем оригинальные, а день равен `1`
|
|
|
+
|
|
|
+Метод **FindIndex** ищет **позицию** (индекс) элемента в списке. Если элемент в списке есть, то возвращает целое от "0" и выше, а если нет, то "-1".
|
|
|
+
|
|
|
+А дальше мы либо добавляем новую дату во временный список, либо увеличиваем счетчик у найденной даты.
|
|
|
+
|
|
|
+Осталось только вернуть отсортированный результат. Для этого в **C#** есть очень мощный инструмент - [**LINQ**](https://metanit.com/sharp/tutorial/15.1.php).
|
|
|
+
|
|
|
+```cs
|
|
|
+...
|
|
|
+return dateTimeWithCounterList
|
|
|
+ .OrderByDescending(item => item.Counter)
|
|
|
+ .ThenBy(item => item.DateTimeProp)
|
|
|
+ .Select(item => item.DateTimeProp)
|
|
|
+ .ToList();
|
|
|
+```
|
|
|
+
|
|
|
+**OrderByDescending** - сортирует исходный список по убыванию. В параметрах пишется лямбда функция, где *item* текущий элемент списка, а после "=>" свойство элемента, по которому производится сортировка. У нас по ТЗ первое условие сортировки по убыванию популярности, поэтому используем свойство Counter. Для прямой сортировки (по возрастанию) есть метод *OrderBy*.
|
|
|
+
|
|
|
+**ThenBy** (ЗатемПо) - при совпадающих свойствах *популярность* сортировка будет производиться по полю *дата*. У метода *ThenBy* есть пара *ThenByDescending*. Методов *ThenBy* после *OrderBy* может быть несколько.
|
|
|
+
|
|
|
+**Select** - выбирает из объекта нужные свойства. Нам из этого объекта нужна только дата. (Если нужно выбрать несколько объектов, то они перечисляются через запятую: `Select(item => item.Prop1, item.Prop2, item.Prop1 + item.Prop2)`)
|
|
|
+
|
|
|
+**ToList** преобразует полученный после сортировки объект (IEnumerable) в список, который и возвращается методом.
|
|
|
+
|
|
|
+
|
|
|
#### Вариант 2. Новый код с использованием словарей
|
|
|
|
|
|
В этом варианте мы обойдемся без дополнительных классов - объявим словарь, в котором ключём будет дата, а значением - количество повторений этой даты.
|
|
|
@@ -215,59 +246,19 @@ public List<DateTime> PopularMonths(
|
|
|
|
|
|
// дальше не проверено
|
|
|
if (dateTimeCounterDictionary.ContainsKey(dateMonthStart)) {
|
|
|
- dateTimeCounterDictionary[dateMonthStart] = Tuple.Create(
|
|
|
- dateMonthStart,
|
|
|
- dateTimeCounterDictionary[dateMonthStart].Item2 + 1
|
|
|
- );
|
|
|
+ dateTimeCounterDictionary[dateMonthStart] = dateTimeCounterDictionary[dateMonthStart] + 1
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- /*
|
|
|
- дата есть - увеличиваем счетчик
|
|
|
- свойства кортежа неизменяемые,
|
|
|
- поэтому перезаписываем текущий элемент
|
|
|
- новым кортежем,
|
|
|
- который создаем статическим методом
|
|
|
- */
|
|
|
- dateTimeCounterDictionary[dateMonthStart] = Tuple.Create(
|
|
|
- dateTimeCounterDictionary[dateMonthStart].Item1,
|
|
|
- );
|
|
|
+ dateTimeCounterDictionary[dateMonthStart] = 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return dateTimeWithCounterList
|
|
|
- .OrderByDescending(item => item.Item2)
|
|
|
- .ThenBy(item => item.Item1)
|
|
|
- .Select(item => item.Item1)
|
|
|
- .ToList();
|
|
|
+ // TODO возврат списка не реализован
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-Для вычисления начала месяца мы использовали один из конструкторов класса **DateTime(year, month, day, hour, minutes, seconds)**, где год и месяц берем оригинальные, а день равен `1`
|
|
|
-
|
|
|
-Метод **FindIndex** ищет **позицию** (индекс) элемента в списке. Если элемент в списке есть, то возвращает целое от "0" и выше, а если нет, то "-1".
|
|
|
-
|
|
|
-А дальше мы либо добавляем новую дату во временный список, либо увеличиваем счетчик у найденной даты.
|
|
|
-
|
|
|
-Осталось только вернуть отсортированный результат. Для этого в **C#** есть очень мощный инструмент - [**LINQ**](https://metanit.com/sharp/tutorial/15.1.php).
|
|
|
-
|
|
|
-```cs
|
|
|
-...
|
|
|
-return dateTimeWithCounterList
|
|
|
- .OrderByDescending(item => item.Counter)
|
|
|
- .ThenBy(item => item.DateTimeProp)
|
|
|
- .Select(item => item.DateTimeProp)
|
|
|
- .ToList();
|
|
|
-```
|
|
|
-
|
|
|
-**OrderByDescending** - сортирует исходный список по убыванию. В параметрах пишется лямбда функция, где *item* текущий элемент списка, а после "=>" свойство элемента, по которому производится сортировка. У нас по ТЗ первое условие сортировки по убыванию популярности, поэтому используем свойство Counter. Для прямой сортировки (по возрастанию) есть метод *OrderBy*.
|
|
|
-
|
|
|
-**ThenBy** (ЗатемПо) - при совпадающих свойствах *популярность* сортировка будет производиться по полю *дата*. У метода *ThenBy* есть пара *ThenByDescending*. Методов *ThenBy* после *OrderBy* может быть несколько.
|
|
|
-
|
|
|
-**Select** - выбирает из объекта нужные свойства. Нам из этого объекта нужна только дата. (Если нужно выбрать несколько объектов, то они перечисляются через запятую: `Select(item => item.Prop1, item.Prop2, item.Prop1 + item.Prop2)`)
|
|
|
-
|
|
|
-**ToList** преобразует полученный после сортировки объект (IEnumerable) в список, который и возвращается методом.
|
|
|
|
|
|
## Использование созданной библиотеки
|
|
|
|