Как удалить из списка, когда итоговые значения по дате равны нулю

#c# #list

#c# #Список

Вопрос:

У меня есть список транзакций на C #

 public class Transaction
{
        public string effectiveDate;
        public string transactionType;
        public double grossAmount;
        public double netAmount;
}
  

Разные типы транзакций хранятся в разных списках, которые заполняются извлечением данных из базы данных.
В конце он выдает отчет о детализированных транзакциях.

Допустим, 15 числа месяца мне выплачивается ежемесячная плата за администрирование в размере 1,50 долл. В феврале плата отменяется, и у меня есть транзакция отмены. Итак, теперь в моем списке у меня есть

 '2020-01-15', 'Admin fee', 1.5, 1.5
'2020-02-15', 'Admin fee', 1.5, 1.5
'2020-02-15', 'Admin fee', -1.5, -1.5
'2020-03-15', 'Admin fee', 1.5, 1.5
  

Как я могу удалить или пропустить плату за администрирование в феврале, если они равны нулю?

В других случаях у меня может быть 10 или более транзакций того же типа в тот же день, которые будут отменены, то есть 10 платежей, полученных и отмененных с той же датой вступления в силу.

Является ли сортировка по дате, повторение и сохранение общего количества значений до тех пор, пока я не перейду к новой дате, а затем сравнение с нулем самым простым / приятным способом?

Я знаю, что это было бы проще сделать в SQL с группой, имея sum <> 0, но значения хранятся в базе данных в виде символов с $ и запятой и начальным пробелом и т.д., Поэтому я не могу пойти этим путем. По разным причинам, даже если я заменяю / replace / replace / convert данные.

Спасибо

Комментарии:

1. Примечание: зачем сохранять effectiveDate как string ? Поскольку это некоторая дата, DateTime effectiveDate будет более естественным

2. Добро пожаловать в StackOverflow. Пожалуйста, поделитесь с нами своими попытками узнать, как вы пытались решить проблему.

3. @DmitryBychenko Справедливый вопрос Каждый год выполняется задание ежегодного отчета, извлекающее соответствующие данные из многих таблиц и помещающее в одну таблицу транзакций. Исторически с этой таблицей не выполнялось никаких операций, поэтому они просто сохраняли все в виде строк. Затем эта таблица была прочитана и загружена в обычный текстовый файл. Вот почему в нем есть все форматирование и интервалы. Затем было написано приложение vb для создания файлов csv. Я думаю, именно тогда форматирование начало удаляться. Затем я пришел и преобразовал вывод XML в C #. Это была моя первая работа на c # несколько лет назад. Было бы много возможностей для улучшения.

Ответ №1:

Вы можете попробовать Linq для данного списка, скажем

   var myList = new List<Transaction>() {
    new Transaction() {
      effectiveDate = "2020-01-15",
      transactionType = "Admin fee",
      grossAmount = 1.5,
      netAmount = 1.5},

    new Transaction() {
      effectiveDate = "2020-02-15",
      transactionType = "Admin fee",
      grossAmount = 1.5,
      netAmount = 1.5},

    new Transaction() {
      effectiveDate = "2020-02-15",
      transactionType = "Admin fee",
      grossAmount = -1.5,
      netAmount = -1.5},

    new Transaction() {
      effectiveDate = "2020-03-15",
      transactionType = "Admin fee",
      grossAmount = 1.5,
      netAmount = 1.5},
  };
  

Вы можете поместить запрос Linq:

  1. Мы GroupBy выполняем транзакции с тем же effectiveDate и transactionType
  2. Проверьте, не равно ли Sum of netAmount 0
  3. Сгладить ( SelectMany с последующим ToList ) группы обратно в список

Код:

   using System.Linq;

  ...

  myList = myList
    .GroupBy(t => new { t.effectiveDate, t.transactionType })
    .Where(group => group.Sum(t => t.netAmount) != 0)
    .SelectMany(group => group)
    .ToList();
  

Комментарии:

1. Потрясающе. Возникли проблемы с запуском из-за точности double. Сумма транзакций была «не совсем» нулевой, поэтому они все еще появлялись. Исправлено с помощью .Where(group => Math.Round(group.Sum(t => t.netAmount),2) != 0) , но теперь появляется множество новых улучшений, которые можно внести. В настоящее время у меня есть 43 разных списка транзакций. Каждый раз, когда создается новая транзакция, я должен создавать новый список и новый код для вывода этого списка. Используя Linq, я мог бы иметь только один список и обрабатывать его совершенно по-другому. Хотя это большее изменение, которое мне может быть запрещено. Спасибо! (Я думаю) 🙂

Ответ №2:

Я думаю, вы могли бы использовать LinQ для группировки ваших результатов по дням и типу, а затем вычислить сумму сгруппированных элементов. Когда сумма ==0 пропускается…

Ответ №3:

 List<Transaction> transactions;
var noUnderZeroFees = transactions.Where(x => x.netAmount > 0).ToList<Transaction>();
//noUnderZeroFees will contains Transaction items with more then Zero netAmount.
  

Попробуйте поискать больше о LINQ

Ответ №4:

Вы можете использовать Linq:

 List<Transaction> loList = new List<Transaction>();
loList.Add(new Transaction()
{
    effectiveDate = "2020-01-15",
    transactionType = "Admin fee",
    grossAmount = 1.5,
    netAmount = 1.5
});
loList.Add(new Transaction()
{
    effectiveDate = "2020-02-15",
    transactionType = "Admin fee",
    grossAmount = 1.5,
    netAmount = 1.5
});
loList.Add(new Transaction()
{
    effectiveDate = "2020-02-15",
    transactionType = "Admin fee",
    grossAmount = -1.5,
    netAmount = -1.5
});
loList.Add(new Transaction()
{
    effectiveDate = "2020-03-15",
    transactionType = "Admin fee",
    grossAmount = 1.5,
    netAmount = 1.5
});

foreach (var loGTrans in loList.GroupBy(item => new { item.transactionType, item.effectiveDate }).Where(item => item.Sum(t => t.netAmount) != 0))
{
    Console.WriteLine($"Type: {loGTrans.Key.transactionType}, Date: {loGTrans.Key.effectiveDate} -> Gross-Sum: ${loGTrans.Sum(item => item.grossAmount)} Net-Sum:${loGTrans.Sum(item => item.netAmount)}");
}
  

Ответ №5:

Сначала вы вводите GroupBy() TransactionType, а затем вычисляете Sum() значение netAmount для каждой группы. С помощью Where() -инструкции вы включаете только те группы, которые соответствуют фильтру, а затем вы растворяете группы с помощью SelectMany()

     private IEnumerable<Transaction> FilterNetZero(IEnumerable<Transaction> list)
    {
        return list.GroupBy(s => s.transactionType)
                   .Where(group => group.Sum(s => s.netAmount) != 0)
                   .SelectMany(group => group);
    }