Запрос IEnumerable для объектов с похожими атрибутами и в течение определенного временного порога - PullRequest
1 голос
/ 17 июня 2011

У меня есть IEnumerable, полный объектов, которые мы используем для представления действий пользователя. Это для конечной цели отображения списка самых последних действий, предпринятых в системе. Этот список может быть довольно длинным, и пользователи запросили 24-часовой период для списка. Я хочу выполнить в этом списке некоторые действия, похожие на то, что делает Facebook для лайков и комментариев. Например, вместо перечисления всех 37 обновлений, выполненных конкретным пользователем, я могу перечислить этого пользователя x обновленного 37 лет.

Эти объекты имеют имя пользователя и дату и время для действия, предпринятого в качестве атрибута, так что информацию достаточно легко выбрать. Мне нужна помощь с лучшим способом, чтобы программно определить, что нужно раздавить. В идеале я думаю, например, если 1000+ человек обновятся в нашей системе менее чем за 10 минут одним и тем же пользователем, то это будет импорт, а не ручное редактирование, и я удалю их из списка действий и заменю на «так и так запустил импорт "

Как бы я запросил IEnumerable для объектов с тем же именем пользователя и в пределах определенного диапазона дат?

Редактировать: Единственное, о чем я вначале могу думать, это перебирать Enumerable для каждого возможного пользователя и для каждого возможного 10-минутного периода времени. Хотя это звучит ужасно неэффективно, и я явно не осведомлен о доступных вариантах.

Ответы [ 2 ]

1 голос
/ 17 июня 2011

Если вы можете использовать Linq, вы можете создать GroupBy для имени пользователя, которое будет группировать все элементы по имени пользователя, тогда вам просто нужно вытащить два списка данных на основе вашего желаемого временного порога.

Допустим, у вас есть список таких объектов

void Main()
{
    DateTime threshold = DateTime.Now.AddMinutes(-10);

    IEnumerable<UserAction> unfilteredActions = new List<UserAction>
    {
        new UserAction { Action = "INSERT", UserName = "Craig", ExecutedOn = DateTime.Now.AddMinutes(-15) },
        new UserAction { Action = "UPDATE", UserName = "Craig", ExecutedOn = DateTime.Now },
        new UserAction { Action = "DELETE", UserName = "James", ExecutedOn = DateTime.Now }
    };

    var userActions = unfilteredActions.Where(action => action.ExecutedOn > threshold).GroupBy(k => k.UserName);
}

public class UserAction
{
    public string Action {get;set;}
    public string UserName {get;set;}
    public DateTime ExecutedOn {get;set;}
}

Вы также можете работать с группировкой, как

foreach (var grp in unfilteredActions.GroupBy(k => k.UserName))
{
    foreach(UserAction action in grp.Where(a => a.ExecutedOn > threshold))
    {
        Console.Out.WriteLine(String.Format("{0} {1} {2}", action.UserName, action.Action, action.ExecutedOn));
    }
}
0 голосов
/ 28 июня 2011

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

Это проблема кластеризации. Я написал и опубликовал библиотеку для выполнения K означает кластеризацию на объектах в IEnumerable. Процесс идет примерно так:

var clusters = SharpLearning.Clustering.KCluster(k, iterations, listOfIClusterableObjects);

foreach (var cluster in clusters) {
    // Process some data.
    // clusters is a List<Cluster<T>> where your objects can be viewed in the .Members attribute
}

Класс Cluster, содержащий два алгоритма расстояния, интерфейс IClusterable и алгоритм KCluster, представлены в C # Библиотеке машинного обучения

...