Question

I have a dataset that I am outputting to a list in the following way:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;


using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

class Program
{
    static void Main(string[] args)
    {
        List<object> myList = new List<object>();

    int i = 1;
    using (StreamReader reader = new StreamReader("file.dat"))
    {
        string line;
        var locations = new Dictionary<string, int[]>() {
            {"210", new [] {405, 4, 128, 12, 141, 12, 247, 15, 121, 3}}, 
            {"310", new [] {321, 4, 112, 12, 125, 12, 230, 15, 105, 3}}, 
            {"410", new [] {477, 4, 112, 12, 125, 12, 360, 15, 105, 3}} 
        };

        while ((line = reader.ReadLine()) != null)
        {


            var lineStart = line.Substring(0, 3);

            if (lineStart == "210" || lineStart == "310" || lineStart == "410")
            {
                var currentLocations = locations[lineStart];
                var letters = line.Substring(currentLocations[0], currentLocations[1]);

                var tvolume =
                    int.Parse(line.Substring(currentLocations[2], currentLocations[3])) +
                    int.Parse(line.Substring(currentLocations[4], currentLocations[5]));

                var tprice = long.Parse(line.Substring(currentLocations[6], currentLocations[7]));
                var mvolume = tprice * tvolume * 0.01 * 0.0000001;
                var currency = line.Substring(currentLocations[8], currentLocations[9]);

                myList.Add(i);
                myList.Add(lineStart);
                myList.Add(letters);
                myList.Add(tvolume);
                myList.Add(tprice);
                myList.Add(mvolume);
                myList.Add(currency);

                // double total = myList.

                Console.WriteLine(i);
                Console.WriteLine(lineStart);
                Console.WriteLine(letters);
                Console.WriteLine(tvolume * 0.01);
                Console.WriteLine(tprice * 0.0000001);
                Console.WriteLine("{0:N}", mvolume);
                Console.WriteLine(currency + "\n");
                i = i + 1;
            }

        }
        int index = 0;
        Dictionary<string, int> tvolumeDictionary = new Dictionary<string, int>();
        Dictionary<string, long> mvolumeDictionary = new Dictionary<string, long>();
        string listLetters;

        foreach (object item in myList)
        {
            switch (index % 7)
            {
                case 2:
                    listLetters = item.ToString();
                    if (!tvolumeDictionary.Keys.Contains(listLetters))
                    {
                        tvolumeDictionary.Add(listLetters, 0);
                        mvolumeDictionary.Add(listLetters, 0);
                    }
                    break;
                case 3:
                    listLetters = myList[index - 1].ToString();
                    tvolumeDictionary[listLetters] = tvolumeDictionary[listLetters] + (int)item;
                    break;
                case 5:
                    listLetters = myList[index - 3].ToString();
                    mvolumeDictionary[listLetters] = mvolumeDictionary[listLetters] + long.Parse(item.ToString());
                    break;
            }
            index++;
        }

                //   Console.WriteLine(myList.Count);

        foreach (KeyValuePair<string, int> entry in tvolumeDictionary)
        {
            Console.WriteLine("{0} tvolume: {1} mVolume: {2}", entry.Key, entry.Value, mvolumeDictionary[entry.Key]);
        }

    }
}

}

File.dat, has thousands of lines to it, of which this will return several hundred. I wish to provide a breakdown of the numeric totals, for each "letters" (there are only about 4 categories in letters). AAAA, BBBB, CCCC and DDDD. If this was excel, i'd like it to do the subtotal function per change in letters column, but the catch here is that they are not in order.

The desired output is

 AAAA: TOTAL TVOLUME: TOTAL MVOLUME 
 BBBB: TOTAL TVOLUME: TOTAL MVOLUME
 CCCC: TOTAL TVOLUME: TOTAL MVOLUME
 DDDD: TOTAL TVOLUME: TOTAL MVOLUME

(above format not essential).

Was it helpful?

Solution

[EDIT] The previous answer has been deleted by a moderator and I can't undelete it, so I'm posting under a different answer. As it seems you would like to have more flexibility when working with the extracted data, I strongly recommend using a custom class and Linq over a list with the custom class objects:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;

class Program
{
    public class EntryLine
    {
        public int I { get; set; }
        public string LineStart { get; set; }
        public string Letters { get; set; }
        public int TVolume { get; set; }
        public long TPrice { get; set; }
        public double MVolume { get; set; }
        public string Currency { get; set; }

    }

    static void Main(string[] args)
    {
        List<EntryLine> myList = new List<EntryLine>();
        int i = 1;
        using (StreamReader reader = new StreamReader("file.dat"))
        {
            string line;
            var locations = new Dictionary<string, int[]>() {
            {"210", new [] {405, 4, 128, 12, 141, 12, 247, 15, 121, 3}}, 
            {"310", new [] {321, 4, 112, 12, 125, 12, 230, 15, 105, 3}}, 
            {"410", new [] {477, 4, 112, 12, 125, 12, 360, 15, 105, 3}} 
        };

            while ((line = reader.ReadLine()) != null)
            {
                var lineStart = line.Substring(0, 3);

                if (lineStart == "210" || lineStart == "310" || lineStart == "410")
                {
                    var currentLocations = locations[lineStart];
                    var letters = line.Substring(currentLocations[0], currentLocations[1]);

                    var tvolume =
                        int.Parse(line.Substring(currentLocations[2], currentLocations[3])) +
                        int.Parse(line.Substring(currentLocations[4], currentLocations[5]));

                    var tprice = long.Parse(line.Substring(currentLocations[6], currentLocations[7]));
                    var mvolume = tprice * tvolume * 0.01 * 0.0000001;
                    var currency = line.Substring(currentLocations[8], currentLocations[9]);

                    myList.Add(new EntryLine()
                    {
                        I = i,
                        LineStart = lineStart,
                        Letters = letters,
                        TVolume = tvolume,
                        TPrice = tprice,
                        MVolume = mvolume,
                        Currency = currency
                    });
                    i = i + 1;
                }
            }

            var x = myList.GroupBy(g => new { g.Letters, g.Currency })
                .Select(a => new { a.Key.Letters, a.Key.Currency, TSum = a.Sum(s => s.TVolume), MSum = a.Sum(s => s.MVolume) });

            foreach (var item in x)
            {
                Console.WriteLine("{0} currency: {1} tvolume: {2} mVolume: {3}", item.Letters, item.Currency, item.TSum, item.MSum);
            }
        }
    }
}

OTHER TIPS

You need to break out of your display loop.

Try adding

If (i > 3) break; // Exit while loop

To the line after the i counter is incremented ( the i= i+1; line).

You could use a Dictionary<string, long> to keep track of the totals. You can either add all the known keys with a value of 0 or check to see if the dictionary contains a value before adding to the value. Something like this:

Dictionary<string, long> values;
long value = code to get the value;
string key = code to get the key;
if(values.ContainsKey(key))
    values[key] += value;
else
    values[key] = value;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top