views:

52

answers:

1

I am reading a txt file for strings that represent integers. The file is space delimited. I have created an array[10,2]. Everytime the strings 1~10 is found in the file I increment array[n,0] by 1. I also feed array[n,1] with numbers 1~10.

i.e. txt file contents:

1/1/1 10/1/2001 1 1 10 2 2 3 1 5 10 word word 3 3 etc..
  • streamreader reads 1/1/1 and determines that is is not 1~10
  • streamreader reads 10/1/2001 and determines that it is not 1~10
  • streamreader reads 1 and ++array[0,0]
  • streamreader reads 1 and ++array[0,0]
  • streamreader reads 10 and ++array[9,0]
  • etc..

The result will be:

  • '1' was found 3 times
  • '2' was found 2 times
  • '3' was found 3 times
  • '5' was found 1 time
  • '10' was found 2 times

My problem is that I need this array placed in order(sorted) by value of column 0 so that it would be:

1
3
2
10
5

The 2nd column in the array is so I can tell what the original(string that was found the most) was. example: array[0,0]= 5//number of times '1' is found in the txt file array[0,1]=1//this is so i know after the sort that array[0,0] value was for '1' array[1,0]= 10//number of times '2' is found in the txt file array[1,1]= 2//this is so i know after the sort that array[1,0] value was for '2'

before I only had a single deminsional array. When I sorted the array I had no way of knowing what the original value of array[0] was so I decided to make a rec array so that array[0,1] switches from 1 to 2 so i could know which string actually shows up the most. does this make more since?

A: 

As a suggestion, perhaps you might consider using a dictionary of int to int. That way you could support n digit values (rather than a fixed range). Though I'm not sure I understand what else the second dimension of the array is storing?

To output them in order using your current solution, assuming your multi-array called _countsIndexedByValues;

var orderedCounts = _countsIndexedByValues.Select((innerArr, i) => new { Count = innerArr[0], Value = i}).OrderBy(u => u.Count);
orderCounts.ToList().ForEach(u => Console.Out.WriteLine(String.Format("'{0}' was found {1} times", u.Value, u.Count);

This is making use of both LINQ and anonymous types... Where I used an anonymous type you could use a Pair or whatever else you want.

Reddog
PS. Instead of doing the .ToList().ForEach() you could of course use your own foreach loop, or a similar ForEach extension method to apply a generic action:public static void ForEach<T>(this IEnumerable<T> source, Action<T> action){ foreach (var item in source) action(item);}
Reddog
way of knowing what the original value of array[0,0] was so I decided to make a rec array so that array[0,1] switches from 1 to 2 so i could know what the which string actually shows up the most. does this make more since?
@user355925 - Hmmmm, if that's the case, then you could definitely ditch the second dimension since you could either resolve it from your original array's index (i.e. value = index + 1) then when it comes to sorting, you can make use of either an anonymous type or some sort of trivial struct (e.g. Pair<int, int> or KeyValuePair<int, int>).
Reddog
@user355925 - I would definitely also suggest going with Dictionary<int, int> anyways for the search/count function since this will already help keep your association of value (as key) to count of occurences (as value). Plus it'll grow/shrink with your value range and the lookup expense is log(N) [where N is size of range of values] which is negligible for your current magnitude of 10 but offers up a much more scalable (and readable) solution.
Reddog