2014-10-27 55 views
6

我有一個叫做_DataCollection的List<List<string>>,其中每個嵌套列表都有相同數量的值。雖然所有字符串都是嵌套列表中的值,但它們是由字母數字字符,空字符串或貨幣值組成的字符串。例如在每個索引中對嵌套列表進行求和的值

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

我需要做的就是拿出一個辦法來總結每個索引的所有值在所有嵌套列表並且將其添加到列表什麼:

newSumList[0] = "N/A" since "tom" + "dick" + "harry" + "bob" can't be aggregated. 
newSumList[1] = "N/A" since "abc" + "xyz" + "" + "" can't be aggregated. 
newSumList[2] = "1125.36" 
newSumList[3] = "397" even though the last value of the last nested list is "". 

基本上,總所有數字每個索引的嵌套列表中的值。

我能想到的唯一方法是迭代這些並保持運行總數,但我想知道是否可以使用LINQ或其他方法來完成這項工作。

回答

4

你在這裏。

var list = new List<List<string>> 
{ 
    new List<string> {"tom", "abc", "$525.34", "$123"}, 
    new List<string> {"dick", "xyz", "$100", "$234"}, 
    new List<string> {"harry", "", "$250.01", "$40"}, 
    new List<string> {"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("en-US"), out num) 
              ? num : 0)); 

當然,您可以通過更改NumberStyles標誌和文化信息來指定應該識別爲數字的內容。

1
List<List<string>> _DataCollection=new List<List<string>>(); 
      _DataCollection.Add(new List<string> {"tom", "abc", "$525.34", "$123"}); 

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

      List<string> newSumList = new List<string>(); 

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

我已經實施了這個&它給了我結果。

9

試試這個: -

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)); 

工作Fiddle

1
// Replace $value with value and remove all non-value strings 
var dollars = _DataCollection 
    .Select(l => l.Select(str => str.Contains('$') ? str.Split('$')[1] : string.Empty)); 

var newSumList = new List<double>(); 

// Add all values in a new list 
for (int i = 0; i < _DataCollection[0].Count; i++) 
{ 
    double toAdd = 0; 
    foreach (var entry in dollars) 
    { 
     // If entry is a value, parse it, 0 otherwise 
     var value = entry.ElementAt(i) != string.Empty ? double.Parse(entry.ElementAt(i)) : 0; 
     toAdd = toAdd + value; 
    } 
    newSumList.Add(toAdd); 
} 
newSumList.ForEach(Console.WriteLine); 
4

或者,對於不同的方法,不需要與GroupBy重新排列順序:

 var culture = new CultureInfo("en-US"); 
     List<string> sums = 
      _DataCollection.Count == 0 
      ? new List<string>() 
      : 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, culture, out val) ? (decimal?)val : (decimal?)null; }) 
         .Aggregate((decimal?)0, (sum, val) => sum + val)) 
      .Select(sum => sum.HasValue ? sum.Value.ToString(culture) : "N/A") 
      .ToList(); 
0

不反覆多次,支持空源列表

var list = new List<string[]> 
{ 
    new [] {"tom", "abc", "$525.34", "$123"}, 
    new [] {"dick", "xyz", "$100", "$234"}, 
    new [] {"harry", "", "$250.01", "$40"}, 
    new [] {"bob", "", "$250.01", ""} 
}; 
var cutlure = new CultureInfo("en-US"); 
var result = list.Aggregate((decimal[])null, (sums, strings) => 
    { 
     if (sums == null) 
      sums = Enumerable.Repeat(decimal.MinValue, strings.Length).ToArray(); 
     for (int i = 0; i < strings.Length; i++) 
     { 
      decimal value; 
      if (decimal.TryParse(strings[i], NumberStyles.Currency, cutlure, out value)) 
       sums[i] = (sums[i] == decimal.MinValue) ? value : sums[i] + value; 
     } 
     return sums; 
    }, 
    sums => sums.Select(sum => (sum == decimal.MinValue) ? "N/A" : sum.ToString()).ToArray()); 
相關問題