简体   繁体   中英

How to remove from a List when total values by date net to zero

I have a C# List of transactions

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

Different transactionTypes are stored in different lists which are populated pulling data from database. At the end it spits out a statement of itemised transactions.

Lets say I have a monthly admin fee $1.50 paid on 15th of the month. In February the fee is waived, and I have a reversal transaction. So now in my list I have

'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

How can I remove or skip the Feb admin fees if they nett out to zero?

In other instances I might have 10 or more transactions of the same type on the same day that get reversed, ie 10 payments received and reversed with same effective date.

Is sorting by date, iterating and keeping running total of values until I get to a new date then comparing to zero the easiest/nicest way?

I know this would be easier to do in the SQL with group by having sum <> 0, but the values are stored in database as chars with $ and comma and leading trailing whitespace etc so I cant go that way. For various reasons, not even if I replace/replace/replace/convert the data.

Thanks

You can try Linq , for given list, say

  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},
  };

You can put Linq query:

  1. We GroupBy transactions with the same effectiveDate and transactionType
  2. Check if Sum of netAmount is not 0
  3. Flatten ( SelectMany followed by ToList ) groups back to list

Code:

  using System.Linq;

  ...

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

I think, you could use LinQ to group your results by day and type and then calculate the sum of the grouped elements. When sum==0 skip...

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

Try to search more about LINQ

You can use 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)}");
}

You first GroupBy() transactionType and then you calculate the Sum() of netAmount foreach group. With the Where() -statement you include only the groups that fit the filter and then you dissolve the groups with 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);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM