Member 12338931 Ответов: 2

Как сделать groupby с помощью list<list<int> и return list<list<int> В C#?


Мои данные начинаются с объекта JSON:
JSON
    {"page":"1",
     "per_page":10,
     "total":100,
     "total_pages":10,
     "data":[{"id":1,
              "userId":1,
              "userName":"Jim Silver", 
              "timestamp":16425382171,
              "txnType":"debit",
              "amount":"$1,000.07",
              "location":{"id":2,
                          "address":"654, Somewhere, Some Street", 
                          "city":"Some City",
                          "zipCode":12345},
                          "ip":"202.210.105.105"},
             {"id":2," ...}
             {"id":3," ...}
              ...
             {"id":n," ...}]


Мне нужно получить идентификатор пользователя и сумму в список<list<int>> который я сделал здесь:

var model = JsonConvert.DeserializeObject<TxnResponse>(rawJSON);
var elements = model.data;

List<List<int>> userTxns = new List<List<int>>(elements.Count);
List<int> record = null;

int userID = 0;
int userAmount = 0;

for (int row = 0; row < elements.Count; row++)
{
    userID = elements[row].userId;
    userAmount = Convert.ToInt32(Math.Floor(decimal.Parse(model.data[row].amount, System.Globalization.NumberStyles.Currency)));

    record = new List<int>();
    record.Add(userID);
    record.Add(userAmount);

    userTxns.Add(record);
}

return userTxns.GroupBy();


Результат должен выглядеть примерно так при печати на экране (консоль.WriteLine(Строка.Join ("\n", список.Выберите(x => String.Join(" ", x))));):
1 1000
2 2000
3 3000
4 4000

Без Group By, если объект JSON имеет 10 элементов данных, у меня есть 10 записей (userId, amount).

Модель:

public class TxnResponse
{
    public string page { get; set; }
    public int per_page { get; set; }
    public int total { get; set; }
    public int total_pages { get; set; }
    public List<data> data { get; set; }
}


public class data
{
    public int id { get; set; }
    public int userId { get; set; }
    public string userName { get; set; }
    public object timestamp { get; set; }
    public string txnType { get; set; }
    public string amount { get; set; }
    public Location location { get; set; }
    public string ip { get; set; }
}

public class Location
{
    public int LocationID { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public int ZipCode { get; set; }
}

Как мне сделать GroupBy по идентификатору пользователя? Спасибо.

Что я уже пробовал:

return userTxns.GroupBy(userID);
return userTxns.GroupBy(u => userID);


но получите "аргументы типа для метода не могут быть выведены из использования..." или "не могут неявно преобразовать тип...".

Richard Deeming

Основываясь на образцовых данных, ваш List<List<int>> это уже обеспечит результат, который вы сказали, что хотите.

Что вы пытаетесь сгруппировать, и какой результат вы ожидаете?

Member 12338931

Я пытаюсь сгруппировать по идентификатору пользователя в объекте userTxns, который содержит списки идентификаторов пользователей и сумм.

Выходные данные должны группировать идентификаторы пользователей и суммировать суммы каждого пользователя следующим образом:

1 1000
2 2000
3 3000
4 4000

где первый столбец-это идентификатор пользователя, а второй - суммированные суммы каждого соответствующего пользователя.

2 Ответов

Рейтинг:
2

OriginalGriff

GroupBy не возвращает записи - он возвращает группы записей, которые (в основном) находятся в парах (ключ, значение).

Взгляните на это: Использование Linq для создания словаря вложенных списков путем группировки из коллекции.[^] Он был написан для группировки журналов на несколько дней, но он будет работать одинаково для идентификаторов и вернет словарь списков - по одному списку для каждого значения идентификатора - с незначительным изменением предложения группировки.


Member 12338931

Спасибо... Я посмотрю, смогу ли я понять, как это реализовать...

Member 12338931

Итак, в вашем примере все файлы журнала примеров находятся в объекте rawFiles, как в

Словарь<string, список<string="">> groups = rawFiles.GroupBy(r => GetDateFromPath(r)).ToDictionary(г =&ГТ; г. Ключ, G =&ГТ; г. Список());

Member 12338931

Кроме того, метод должен возвращать список<list<int> & gt;.

Рейтинг:
18

Richard Deeming

Если вы хотите придерживаться List<List<int>> подход, группировка по первому значению и суммирование второго, что-то вроде этого должно работать:

return userTxns.GroupBy(u => u[0], (key, values) => new List<int> 
{ 
    key, 
    values.Select(l => l[1]).Sum() 
}).ToList();
Лично я был бы склонен использовать словарь вместо этого:
var model = JsonConvert.DeserializeObject<TxnResponse>(rawJSON);
var result = new Dictionary<int, int>(elements.Count);
foreach (data item in model.data)
{
    int userId = item.userId;
    int userAmount = Convert.ToInt32(Math.Floor(decimal.Parse(item.amount, System.Globalization.NumberStyles.Currency)));
    
    if (result.TryGetValue(userId, out int existingAmount))
    {
        userAmount += existingAmount;
    }
    
    result[userId] = userAmount;
}

return result;


Maciej Los

5ed!

Member 12338931

Спасибо. Я получаю следующую ошибку в значениях.Выбрать... линия:

Ошибка CS0266 не может неявно преобразовать тип 'System.Коллекции.Общий.Интерфейс IEnumerable&ЛТ;система.коллекции.универсальный.список<инт&ГТ;&ГТ;' к 'системе.Коллекции.Универсальный.Список<система.коллекции.универсальный.список<инт&ГТ;&ГТ;'. Существует явное преобразование (вы пропускаете приведение?)

Гугл-тов/поиск, Как выполнить приведение (при необходимости). Если вы видите, если/что вызывает ошибку, не могли бы вы опубликовать ответ?

Да, словарь может быть лучше, но я должен вернуть список<List<int>. Спасибо.

Richard Deeming

Просто добавить .ToList() до конца:

return userTxns.GroupBy(...).ToList();

Member 12338931

Что было то было. Большое спасибо.