4

I have

List<string> strs;
double[] values;

where the values array contains the value of each of the string in strs list

Say strs={"abc","def","ghi"} and values={3,1,2} this means "abc" has value 3 and so on.

I wish to sort strs and values ordered by values, such that it becomes

strs={"def","ghi","abc"}
values={3,2,1}

I am using

string[] strsArr = strs.ToArray();
Array.Sort(values, strsArr);//1. sort it ascendingly
strs = strsArr.ToList();
Array.Reverse(strs);//2. reverse it

Is there a way I can sort it in descending sequence directly without 2 phases?

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
william007
  • 17,375
  • 25
  • 118
  • 194
  • Just curious why you aren't using a Dictionary since you're essentially creating a map. Then you can follow the answer from http://stackoverflow.com/questions/289/how-do-you-sort-a-c-sharp-dictionary-by-value – nithins Oct 10 '12 at 03:05
  • `SortedDictionary` would be the way to do. – IAbstract Oct 10 '12 at 03:07
  • @IAbstract Looks like he wants to sort by the values though. SortedDictionary sorts by keys. – nithins Oct 10 '12 at 03:09
  • @william007: sorting by *descending* value means that your values would be sorted like so: `3, 2, 1`. If you want your values, as you state in your expected results, to be `1, 2, 3` then you are sorting by *ascending* value. – IAbstract Oct 10 '12 at 13:31
  • @IAbstract You are right, I have edited the question, thanks for the pointing of mistake ;) – william007 Oct 10 '12 at 17:58

3 Answers3

3

You can use a Dictionary and Linq to solve this.

var dict = new Dictionary<string, double>() 
{ 
           {"abc",3}, 
           {"def",1}, 
           {"ghi",2} 
};
var sorted = dict.OrderByDescending(g => g.Value)
                 .Select(g => g.Key)
                 .ToArray();

Note, unless you have a ToArray() at the end the sorting will be deferred till later enumerated and may accidentally be enumerated multiple times.

Dharun
  • 613
  • 8
  • 26
2

How about this:

var strs = new [] { "abc", "def", "ghi", };
var values = new [] { 3, 1, 2, };

strs =
    strs
        .Zip(values, (s, v) => new { s, v })
        .OrderByDescending(sv => sv.v)
        .Select(sv => sv.s)
        .ToArray();
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0

try use dictionary:

Dictionary<string, double> dictionary = new Dictionary<string, double>();
dictionary.Add("abc", 3);
dictionary.Add("def", 1);
dictionary.Add("ghi", 2);

var sortedDict = dictionary.OrderByDescending(x => x.Value);
double[] values = sortedDict.Select(x => x.Value).ToArray();
List<string> strs = sortedDict.Select(x => x.Key).ToList();
Habibillah
  • 27,347
  • 5
  • 36
  • 56