1

I have a situation where I need to sort arrays and preserve the current key - value pairs.

For example, this array:

(0) = 4
(1) = 3
(2) = 1
(3) = 2

Needs to sort like this

(2) = 1
(3) = 2
(1) = 3
(0) = 4

Retaining the original keys. Array.Sort(myArray) sorts into the right sequence but doesn't keep the indexes. I need a variant that does.

edit Using the links, this seems close to what I want. Do I just need to remove the extra brackets to convert this to vb.net?

myList.Sort((firstPair,nextPair) =>
    {
        return firstPair.Value.CompareTo(nextPair.Value);
    }
);

(also would I intergrate this as a function or something else?)

YsoL8
  • 2,186
  • 5
  • 29
  • 47
  • 1
    You can use a Dictionary. Here's a SO answer on the topic. http://stackoverflow.com/questions/289/how-do-you-sort-a-c-dictionary-by-value – Ken Pespisa May 17 '11 at 15:09
  • That seems to be related to C#. Are they compatible? (sorry, new to vb.net) – YsoL8 May 17 '11 at 15:16
  • 1
    Yes. They use a different syntax, but they're (basically) the same language. – Heinzi May 17 '11 at 15:29

3 Answers3

2

In an array, the order is determined by the indexes (what you call "keys"). Thus, there cannot be an array like this:

(2) = 1
(3) = 2
(1) = 3
(0) = 4

What you need is a data structure that has keys, values and an order (which is independent from the keys). You can use a List(Of KeyValuePair) or (if you use .net 4) List(Of Tuple(Of Integer, Integer)) for this; a few examples are shown in the link provided by Ken in the comment (which I will repeat here for convenience):


EDIT: Another option would be to use LINQ to automatically create a sorted IEnumerable(Of Tuple(Of Integer, Integer)):

Dim a() As Integer = {4, 3, 1, 2}  ' This is your array

Dim tuples = a.Select(Function(value, key) New Tuple(Of Integer, Integer)(key, value))
Dim sorted = tuples.OrderBy(Function(t) t.Item2)

(untested, don't have Visual Studio available right now)

Community
  • 1
  • 1
Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • copy/pasting directly into visual studio generates errors I don't know how to resolve – YsoL8 May 17 '11 at 15:48
  • @YsoL8: Do you understand the code? If no, where are you lost? (And if you don't tell me *which* errors you get, I cannot help you resolve them... ;-)) – Heinzi May 17 '11 at 15:52
  • @Heninzi I get end of statement expected declaring the contents of the array on line 1 and line 2 starting at the new keyword. I also get expression expected on both function keywords. I am pasting this in a sub in a class. – YsoL8 May 17 '11 at 15:58
  • @YsoL8: Ah, the array initializer syntax was broken. Should be fixed now. – Heinzi May 17 '11 at 16:05
  • @heninzi That cleared the error on line 1. The others remain however. (I am trying to resolve them this end, just not sucessfully). Does t need to be dim'ed? – YsoL8 May 17 '11 at 16:11
  • @YsoL8: Nope, t is a parameter of the lambda. What error do you get? – Heinzi May 17 '11 at 16:13
  • Dim tuples = a.Select(Function(ByVal value, ByVal key) New Tuple(Of Integer, Integer)(key, value)) clears the end of statement error starting on new but adds one under the second ByVal. No idea why. – YsoL8 May 17 '11 at 16:15
  • I get expression expected for the function keywords and end of statement expected under the second ByVal in the fix I attempted. – YsoL8 May 17 '11 at 16:22
  • @Ysol8: You definitely don't need the ByVal keywords here. Do you have Option Infer activated for your project? – Heinzi May 17 '11 at 16:26
  • don't know how to activate it - so I guess not – YsoL8 May 17 '11 at 16:30
  • @YsoL8: http://msdn.microsoft.com/en-us/library/bb384665.aspx, see the section "To set Option Infer in the IDE". – Heinzi May 17 '11 at 16:33
  • @Henizi I'm using Visual Studio 2005 which apparently doesn't support Option Infer. – YsoL8 May 17 '11 at 16:47
  • @YsoL8: Ah, ok, so you're targeting .net 2.0, which does not support lambdas nor LINQ either. Sorry, then my solution (and most others that you'll find here) won't work. – Heinzi May 17 '11 at 16:54
  • Ok. a) sorry for wasting your time b) good to know for the future c) bugger – YsoL8 May 17 '11 at 17:02
  • @Ysol8: No problem. I've added another answer, which works on .net 2 and might be helpful. – Heinzi May 17 '11 at 17:05
1

Since you are using .net 2.0 (since you said that you are using Visual Studio 2005 in one of the comments), using an OrderedDictionary might be an option for you, if every array value appears only once. Since OrderedDictionaries are ordered by the key, you could add your array entries to such a dictionary, using

  • the array index as the dictionary value and
  • the array value as the dictionary key (which will be used to order the dictionary).
Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • If you mean that no value can be the same as another - I can't guarantee that (in fact it's quite likely). Fast getting the feeling net 2.0 is antiquated, and upgrading is out of my control. What is the newest version? – YsoL8 May 17 '11 at 17:06
  • @YsoL8: The newest version is 4.0 (Visual Studio 2010). Visual Studio 2008 support 3.5. – Heinzi May 17 '11 at 22:01
0

What you are looking for is storing it as a Dictionary < int,int > and sort by the dictionary by Value.

I think the VB .Net synatx for dictionary is Dictionary( of Int, Int)

Viv
  • 2,515
  • 2
  • 22
  • 26
  • found: http://www.dotnetperls.com/sort-dictionary-vbnet. Will try and post text if good solution – YsoL8 May 17 '11 at 15:21