0

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={1,2,3}

Is there any easy way to achieve this?

4
  • It is better to use Dictionary for your case, instead of two lists Commented Oct 9, 2012 at 12:50
  • Why not use a Dictionary if you have such mappings? Commented Oct 9, 2012 at 12:51
  • Alternatively, if you don't mind storing both arrays in the same object, you could use a SortedList<int, string> Commented Oct 9, 2012 at 13:09
  • @george.zakaryan: This is less of a mapping and more of a list of pairs - I wouldn't class mappings as meaninfully sortable. Commented Oct 9, 2012 at 13:43

6 Answers 6

2

The Array.Sort method has an overload that takes two arrays and sorts both arrays according to the values in the first array, so make an array out of the list:

string[] strsArr = strs.ToArray();

Then sorting them can't be simpler:

Array.Sort(values, strsArr);

And then back to a list, if you need that:

strs = strsArr.ToList();
Sign up to request clarification or add additional context in comments.

Comments

2

You can use Enumerable.Zip, then sort the result, then extract the list of strings.

Something like:

var result = strs.Zip(values, (first, second) => new Tuple<string, double>(first, second))
            .OrderBy(x => x.Item2)
            .Select(x => x.Item1)
            .ToList();

Comments

2

How are you setting up these collections? Or are you given these two parameters?

You could create a StringAndOrder class and use LINQ:

public class StringAndOrder
{
    public string String { get; set; }
    public double Order { get; set; }
}

List<StringAndOrder> list; //create with this structure instead
var orderedStrings = list.OrderBy(item => item.Order).Select(item => item.String);

Comments

2
var sortedStrs = strs.Select((i, s) => new {Value = values[i], Str = s})
                     .OrderBy(x => x.Value)
                     .Select(x => x.Str).ToList();

If you could logically put those values as properties of a class, such as:

class NameAndOrder
{
    public string Name;
    public int Order;
}

Then it would be better and more organized, and then you could do:

var items = new List<NameAndOrder>(strs.Count);

for (var i = 0; i < strs.Count; i++)
{
    items.Add(new NameAndOrder { Name = strs[i], Order = values[i] });
}

items.Sort((a, b) => a.Order.CompareTo(b.Order));

Comments

1

Why Don't you use Dictionary Object..

Dictionary<string, int> dictionary =
    new Dictionary<string, int>();
dictionary.Add("cat", 2);
dictionary.Add("dog", 1);
dictionary.Add("llama", 0);
dictionary.Add("iguana", -1);
// Acquire keys and sort them.
var list = dictionary.Keys.ToList();
list.Sort();

Comments

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

var newArr = strs.Select((s, i) => new { s, i })
                 .OrderBy(x => values[x.i])
                 .Select(x => x.s)
                 .ToArray();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.