6 Stimmen

Das Summieren von Werten über verschachtelten Listen an jedem Index

Ich habe eine List> namens _DataCollection, in der jede der verschachtelten Listen eine gleiche Anzahl von Werten hat. Obwohl alle Zeichenfolgen sind, bestehen die Werte in den verschachtelten Listen aus alphanumerischen Zeichen, leeren Zeichenfolgen oder einem Währungswert. Zum Beispiel

_DataCollection[0] = {"tom", "abc", "$525.34", "$123"}
_DataCollection[1] = {"dick", "xyz", "$100", "$234"}
_DataCollection[2] = {"harry", "", "$250.01", "$40"}
_DataCollection[2] = {"bob", "", "$250.01", ""}

Was ich tun muss, ist eine Möglichkeit zu finden, alle Werte pro Index über alle verschachtelten Listen zu summieren und dies einer Liste hinzuzufügen:

newSumList[0] = "N/A", da "tom" + "dick" + "harry" + "bob" nicht zusammengefasst werden können.
newSumList[1] = "N/A", da "abc" + "xyz" + "" + "" nicht zusammengefasst werden können.
newSumList[2] = "1125.36"
newSumList[3] = "397", auch wenn der letzte Wert der letzten verschachtelten Liste "" ist.

Grundsätzlich alle numerischen Werte in verschachtelten Listen für jeden Index zusammenzählen.

Der einzige Weg, den ich kenne, um dies zu tun, ist, diese durchlaufen und einen laufenden Gesamtbetrag behalten, aber ich frage mich, ob ich dies mit LINQ oder etwas anderem tun kann.

9voto

Rahul Singh Punkte 21353

Versuchen Sie dies:-

decimal _temp =0;
int ListLength = _DataCollection.First().Count();
            var query = _DataCollection.SelectMany(x => x).
                                       Select((v, i) => new { Val = v, Index = i % ListLength })
                                       .GroupBy(x => x.Index)
                                       .Select(z => z.Sum(y => decimal.TryParse(y.Val,out _temp) ? _temp : 0));

Arbeits Fiddle.

4voto

Ondrej Janacek Punkte 12236

Hier haben Sie.

var list = new List>
{
    new List {"tom", "abc", "$525.34", "$123"},
    new List {"dick", "xyz", "$100", "$234"},
    new List {"harry", "", "$250.01", "$40"},
    new List {"bob", "", "$250.01", ""}
};

decimal num;
var itemsPerLine = list[0].Count; // 4
var res = list.SelectMany(line => line);
              .Select((s, i) => new { Text = s, Index = i })
              .GroupBy(i => i.Index % itemsPerLine) // transformed matrix here
              .Select(g => g.Sum(i => 
                   decimal.TryParse(i.Text, NumberStyles.AllowCurrencySymbol | 
                                            NumberStyles.AllowDecimalPoint, 
                                            new CultureInfo("de-DE"), out num) 
                                            ? num : 0));

Sie können natürlich angeben, was als Zahl erkannt werden soll, indem Sie die NumberStyles-Flags und Kulturinformationen ändern.

4voto

dbc Punkte 90210

Oder für einen anderen Ansatz, der keine Umsortierung der Sequenzen mit GroupBy erfordert:

var kultur = new CultureInfo("en-US");
List summen =
    _DataCollection.Count == 0
    ? new List()
    : Enumerable.Range(0, _DataCollection.First().Count)
    .Select(i => _DataCollection.Select(list => list[i])
               .Select(s => { decimal val; return string.IsNullOrEmpty(s) ? (decimal?)0 : decimal.TryParse(s, NumberStyles.Currency, kultur, out val) ? (decimal?)val : (decimal?)null; })
               .Aggregate((decimal?)0, (sum, val) => sum + val))
    .Select(sum => sum.HasValue ? sum.Value.ToString(kultur) : "N/A")
    .ToList();

1voto

Rahul Punkte 2261
List> _DataCollection=new List>();
            _DataCollection.Add( new List {"tom", "abc", "$525.34", "$123"});

            _DataCollection.Add( new List {"dick", "xyz", "$100", "$234"});
            _DataCollection.Add( new List {"harry", "", "$250.01", "$40"});
            _DataCollection.Add( new List {"bob", "", "$250.01", ""});

            List newSumList = new List();

            for (int i = 0; i < _DataCollection.Count; i++)
            {
                decimal Sum = 0;
                string CurrentSumList;
                string Comment;
                decimal amount = 0;
                for (int j = 0; j < _DataCollection.Count; j++)
                {
                    bool IsDecimalAmount=decimal.TryParse( _DataCollection[j][i].Replace('$','0'),out amount);
                    if (IsDecimalAmount)
                    {

                        Sum += amount;
                    }
                    else
                    {
                        Comment = "String";

                    }
                }
                CurrentSumList = Sum.ToString();
                newSumList.Add(CurrentSumList);
            }

Ich habe dies implementiert & es gibt mir das Ergebnis.

1voto

mihai Punkte 4309
// Ersetzen Sie $Wert durch Wert und entfernen Sie alle Nicht-Wert-Zeichenfolgen
var dollars = _DataCollection
    .Select(l => l.Select(str => str.Contains('$') ? str.Split('$')[1] : string.Empty));

var newSumList = new List();

// Fügen Sie alle Werte in einer neuen Liste hinzu
for (int i = 0; i < _DataCollection[0].Count; i++)
{
    double toAdd = 0;
    foreach (var entry in dollars)
    {
        // Wenn der Eintrag ein Wert ist, parsen Sie ihn, andernfalls 0
        var value = entry.ElementAt(i) != string.Empty ? double.Parse(entry.ElementAt(i)) : 0;
        toAdd = toAdd + value;
    }
    newSumList.Add(toAdd);
}
newSumList.ForEach(Console.WriteLine);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X