2013-11-20 85 views
1

我有一個結構數組。我的結構的結構是這樣的:對c中多個元素的結構數組排序#

[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; 
    } 

我填充型TOCRRESULTS像這樣的結構:

TOCRRESULTS MyArray = GetOCRForImage(filename); 

我排序由Y值數組就好使用此:

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

有沒有一種方法可以按Y和X排序,而無需編寫自己的排序程序?

我嘗試使用LINQ:

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

但它從來沒有整理我的數組。

對於原來發布的劇烈變化,我表示歉意。我希望能用一個簡單的例子逃脫。

+0

您的LINQ示例,如此處所寫,不會執行任何操作_by design_。 –

+0

編輯我的答案,應該在你的情況下工作。 – Asik

+0

是的。我將其標記爲答案。謝謝! – Richard

回答

3

最有效的仍然是使用的Array.Sort,避免新的陣列分配:

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

這會由Y排序然後X.如果您願意,您可以輕鬆地將其切換爲按X排序然後按Y排序。

+0

這涉及到一個自定義的排序例程,問題要求不要這樣做。這個問題並沒有問及效率問題。 – Dan

+1

這不是一個排序例程,它是一個與OrderBy/ThenBy示例中使用的比較函數完全相同的比較函數,它只使用X和Y.此處使用的排序例程是Array.Sort()。 – Asik

+1

確切地說,OrderBy使用投影函數,而Array.Sort使用比較函數。這兩者都不是一個排序程序。 – Asik

2

你必須將其重新分配:

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

爲什麼要調用'ToList'?這裏沒有什麼說'List'會比數組更好。 – Dan

+1

@丹:習慣。我會改變它,謝謝。 –

+0

這根本不是對我的數組進行排序。我完全按照上面的方式使用了代碼。 – Richard

1

試試這個:

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

調用陣列上OrderBy返回IEnumerable<MyStructure>類型的新的集合。它不是修改原始數組。一旦你有了新的收藏品,你可以在它上面調用ToArray,並將其重新分配給原始變量。

+0

這將如何幫助我排序X和Y? – Richard

1

您的LINQ解決方案看起來不錯,您確定您正確使用它嗎?與此相反Array.Sort,它是回報IEnumerable,而不是就地排序(如不Array.Sort),所以你將不得不使用

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

你將不得不表現出更多的代碼,如果這個不解決問題。

+0

當我使用這個,我得到一個「不能隱式轉換類型'System.Linq.IOrderedEnumerable ''MyArray []'錯誤 – Richard

+0

@Richard這表明你的」MyArray「標識符不只是一個數組變量 - 它是什麼? – Asik

+0

我只是重寫了整個原始問題,以便更好地展示我正在處理的內容。 – Richard

1

是,實施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); 
    } 
} 
+0

這不是一個排序例程嗎?問題是如何做到的「無需編寫我自己的排序例程」。 – Dan

+0

通過這種方式,您可以可以調用'Array.Sort (MyArray)'而不用每次都定義比較委託'(a,b)=> aYCompareTo(bY)' – Alberto

+0

我明白,但它仍然是一個排序例程。 – Dan