2014-10-27 7 views
6

पर नेस्टेड सूचियों में मूल्यों को सारांशित करना मेरे पास List<List<string>> है जिसे _DataCollection कहा जाता है, जहां नेस्टेड सूचियों में से प्रत्येक के बराबर संख्या होती है। हालांकि सभी तारों, नेस्टेड सूचियों में मान स्ट्रिंग होंगे जिसमें अल्फान्यूमेरिक वर्ण, खाली तार या मुद्रा मान शामिल होंगे। उदाहरण के लिएप्रत्येक इंडेक्स

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

आप निश्चित रूप से निर्दिष्ट कर सकते हैं कि संख्या स्टाइल ध्वज और संस्कृति जानकारी को बदलकर किसी संख्या के रूप में पहचाना जाना चाहिए।

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