3

I have a struct containing song data:

public struct uLib
    {
        public string Path;
        public string Artist;
        public string Title;
        public string Album;
        public string Length;
    }  

My library consists of an array of this uLib. How would I sort this array by say Artist? Is there a native sort function I can call on this type of array, or will I have to "roll my own"?

Krakerjak
  • 449
  • 3
  • 7
  • 17

3 Answers3

16

First of all, that should not be a struct. It's larger than 16 bytes, so you don't get the performance benefits of having a struct. Also, it doesn't represent a single value, so it doesn't make sense semantically to make it a struct. Just make it a class instead.

The Array class has a Sort method that you can use:

Array.Sort(theArray, (x,y) => string.Compare(x.Artist,y.Artist));

If you don't have C# 3 you use a delegate instead of the lambda expression:

Array.Sort(theArray, delegate(uLib x, uLib y) { return string.Compare(x.Artist,y.Artist) } );

Edit:
Here's an example of what your data could look like as a class:

public class ULib {

    private string _path, _artist, _title, _album, _length;

    public string Path { get { return _path; } set { _path = value; } }
    public string Artist { get { return _artist; } set { _artist = value; } }
    public string Title { get { return _title; } set { _title = value; } }
    public string Album { get { return _album; } set { _album = value; } }
    public string Length { get { return _length; } set { _length = value; } }

    public ULib() {}

    public ULib(string path, string artist, string title, string album, string length) {
       Path = path;
       Artist = artist;
       Title = title;
       Album = album;
       Length = length;
    }

}

In C# there there is a short form for a property. Instead of writing code for a private variable and a setter and getter to access it, this creates that automatically:

public string Path { get; set; }
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • That works great. Thanks. You say I shouldn't use a struct, how would you organize this kind of data? – Krakerjak Mar 11 '09 at 11:01
  • Put it in the class - and use properties instead of public fields, too. – Jon Skeet Mar 11 '09 at 11:51
  • Guffa - Thanks for clarifying. Would that get sorted the same way? – Krakerjak Mar 11 '09 at 21:31
  • Yes, only slightly faster as there is 80% less data to move around. :) – Guffa Mar 11 '09 at 22:32
  • @Guffa: would you mind to provide the source of your claim that larger than 16 bytes => no perf gain? thanks – pointernil Dec 21 '10 at 14:48
  • @pointernil: For example here: http://msdn.microsoft.com/en-us/library/ms229017.aspx or http://stackoverflow.com/questions/1082311/why-should-a-net-struct-be-less-than-16-bytes or http://stackoverflow.com/questions/2407691/c-struct-design-why-16-byte-is-recommended-size/2407706 – Guffa Dec 21 '10 at 16:43
1

from u in ULibArray order by u.Artist select u;

John Saunders
  • 160,644
  • 26
  • 247
  • 397
0

Assuming uLibs is an IEnumerable<T>, you can try this:

uLibs.OrderBy(i => i.Artist)

This sorts the uLib instances by using a key; in this case, you've selected Artist to be the key to compare against. Similar sorting is possible against your other fields.

John Feminella
  • 303,634
  • 46
  • 339
  • 357
  • You'll lose the result if you do this, though. The correct way do do this is var orderedLibs = uLibs.OrderBy(i => i.Artist) – erikkallen Mar 11 '09 at 10:49
  • Yes, this is meant to be included as part of another statement. What you do with the result is up to you, of course. – John Feminella Mar 11 '09 at 10:53