2014-09-10 26 views
3

我收到了一些xml數據,如下面的uniqueCD變量列表。讓所有的數據後,我希望它改變根據我自己的要求數據的順序,和順序應該是這樣:如何根據自定義順序排列listitem?

  1. 亞馬遜
  2. Soap.com
  3. Drugstore.com
  4. 沃爾瑪
  5. 目標


var uniqueCD = (from n in xdoc.Descendants("retailer") 
        .Where(x => x.Element("instock").Value.Contains("true")) 
        select n).Distinct(new XElementComparer()).ToList(); 

XML數據從清單歌廳:

<retailers> 
    <retailer> 
    <name>&lt;![CDATA[ Walmart ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Soap.com ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Restockit ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Drugstore.com ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Walgreens.com ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Amazon ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Target ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
</retailers> 
+2

這個「順序」看起來完全是任意的......你如何/在哪裏定義了這個順序? – Belogix 2014-09-10 13:10:05

+0

你在控制XML嗎?您可以將每種零售商的某種元數據關聯起來,您可以使用它來進行排序嗎?例如(假設您在控制XML源),您可以在XML中添加一個''標記,並使用LINQ的'.By()'對列表進行排序。 – 2014-09-10 13:10:07

+0

actly m閱讀多個XML nd形成此爲一個單獨的XML。 – 2014-09-10 13:21:32

回答

2

如果你沒有任何業務邏輯在那裏你可以dervive的算法(即按字母順序排列),那麼我會推薦一個自定義的擴展方法做你的排序。你必須硬編碼,所以它不會是看上高性能,但它會工作:

public static IEnumerable<XElement> CustomSort(this IList<XElement> elms) 
{ 
    yield return elms.FirstOrDefault(x => x.Name == "Amazon"); 
    yield return elms.FirstOrDefault(x => x.Name == "Soap.com"); 

    //etc 

} 

,然後從LINQ語句調用這個方法:

 (from n in xdoc.Descendants("retailer") 
       .Where(x => x.Element("instock").Value.Contains("true")) 
       select n) 
     .Distinct(new XElementComparer()).ToList() 
     .CustomSort().ToList(); 
+0

如果「soap.com」不會在我現有的數據中出現,將會發生什麼情況會發生什麼?它會忽略它或拋出錯誤。 – 2014-09-12 13:33:40

+0

在這種情況下,它會返回任何缺失值的'null' – 2014-09-28 23:38:59

1

您可以嘗試指定零售商名稱映射到合適的數據結構中的排名首選項,例如Dictionary<string, int>

private Dictionary<string, int> retailerRank = new Dictionary<string, int>() 
               { 
                {"Amazon", 1}, 
                {"Soap.com", 2}, 
                ...... 
                ...... 
               }; 

然後創建一個功能基於字典的映射來得到零售商的排名,並在你的LINQ使用功能OrderBy操作:

private int getRetailerRank(string retailer) 
{ 
    var match = retailerRank.FirstOrDefault(o => retailer.Contains(o.Key)); 
    return match.Value == 0 ? int.MaxValue : match.Value; 
} 
.... 
var uniqueCD = (from n in xdoc.Descendants("retailer") 
           .Where(x => x.Element("instock").Value.Contains("true")) 
       select n 
       ).Distinct(new XElementComparer()) 
       .OrderBy(o => getRetailerRank(o.Element("name").Value)) 
       .ToList(); 
0

定義數組與自定義排序值,然後使用數組索引排序值。

var ordering = new [] {"Amazon", "Soap.com"}; 
var orderedCollection = coll.OrderBy(item => Array.IndexOf(ordering, item.SomeProperty));