2

I have an array of structures. The structure of my structs is this:

    [StructLayout(LayoutKind.Sequential)]
    public struct TOCRRESULTSHEADER
    {
        public int StructId;
        public int XPixelsPerInch;
        public int YPixelsPerInch;
        public int NumItems;
        public float MeanConfidence;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct TOCRRESULTSITEM
    {
        public short StructId;
        public short OCRCha;
        public float Confidence;
        public short X;
        public short Y;
        public short Width;
        public short Height;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct TOCRRESULTS
    {
        public TOCRRESULTSHEADER Hdr;
        public TOCRRESULTSITEM[] Item;
    }

I am populating a structure of type TOCRRESULTS like this:

  TOCRRESULTS MyArray = GetOCRForImage(filename);

I am sorting the array by the Y values just fine using this:

 Array.Sort<TOCRRESULTSITEM>(MyArray.Item, (a,b) => a.Y.CompareTo(b.Y));

Is there a way to sort by Y and X without having to write my own sorting routine?

I tried using LINQ:

 var newarray = OCRLetterArray.Item.OrderBy(x => x.Y).ThenBy(x => x.X).ToArray();

but it never sorted my array.

I apologize for the drastic change from my original posting. I was hoping I could get away with a simple example.

3
  • Your LINQ example, as written here, won't do anything by design. Commented Nov 20, 2013 at 17:54
  • Edited my answer, should work in your case. Commented Nov 20, 2013 at 19:03
  • Yes it did. I marked it as the answer. THanks! Commented Nov 20, 2013 at 19:07

5 Answers 5

3

Most efficient would still be to use Array.Sort, avoiding the allocation of a new array:

    Array.Sort(MyArray.Item, (a, b) =>
    {
        var comparison = a.Y.CompareTo(b.Y);
        return comparison == 0 ? a.X.CompareTo(b.X) : comparison;
    });

This will sort by Y then by X. You can easily switch it around to sort by X then by Y if you wish.

Sign up to request clarification or add additional context in comments.

3 Comments

This involves a custom sorting routine, which the question asks not to do. The question doesn't ask about efficiency.
That's not a sorting routine, it's a comparison function exactly like the ones used in the OrderBy/ThenBy examples, only it uses both X and Y. The sorting routine used here is Array.Sort().
To be exact, OrderBy uses a projection function whereas Array.Sort uses a comparison function. Neither is a sort routine.
3

You have to reassign it:

var orderedArray = MyArray.OrderBy(a => a.Y).ThenBy(a => a.X).ToArray();

4 Comments

Why call ToList? There's nothing here that says a List would be better than an array.
This is not sorting my array at all. I used the code exactly as above.
The actual code is code that I inherited and it signicantly more complex that my original question. I am modifying my original question now...
@Richard No, LINQ doesn't do an in place sort. Instead it will return a new array with the given ordering. If it's important to do an in place sort you could copy it back to the first array.
1

Try this:

MyArray = MyArray.OrderBy(a => a.Y).ToArray();

Calling OrderBy on the array returns a new collection of type IEnumerable<MyStructure>. It doesn't modify the original array. Once you have the new collection, you can call ToArray on it, and reassign it to the original variable.

1 Comment

How will this help me sort by X and Y?
1

Your LINQ solution looks fine, are you sure you are using it correctly? In contrast to Array.Sort, it is returns the new IEnumerable instead of sorting in-place (as does Array.Sort), so you would have to use

MyArray = MyArray.OrderBy(a => a.Y).ThenBy(a => a.X).ToArray();

You would have to show more code if this does not solve the problem.

3 Comments

When I use this, I get a "Cannot implicitly convert type 'System.Linq.IOrderedEnumerable<MyArray>' 'MyArray[]' error
@Richard this suggests that your "MyArray" identifier isn't just an array variable - what is it?
I just rewrote the entire original question to better show what I am working with.
1

Yes, implement IComparable

public struct MyStructure: IComparable, IComparable<MyStructure>
 {
      public int X;
      public int Y;

    public int CompareTo(MyStructure other)
    {
        return Y.CompareTo(other.Y);
    }

    public int CompareTo(object obj)
    {
        return CompareTo((MyStructure)obj);
    }
 }

7 Comments

Isn't this a sorting routine? The question asks how to do it "without having to write my own sorting routine."
In this way you can call Array.Sort<MyStructure>(MyArray) without defining every time the comparison delegate (a,b) => a.Y.CompareTo(b.Y)
I understand that, but it's still a sorting routine.
I don't understand.. you need some kind of routine or algorithm to sort a custom object or structure
@Dan CompareTo() is not a sorting routine, it's a comparison function.
|

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.