2012-04-26 21 views
0

列表說我有一個項目迭代以起始字母

-17" 屏幕
列表 - 100GB HD
-10788火線
-Lock電纜
-Monitor
- 鼠標
- 鍵盤
- USB

我要重複的,d到F等從開始到C項的列表...

I want this to run for items starting from A to items starting C 
    @foreach (var item in Model.Items.OrderBy(i => i.Title)) 
      { 
// Code 
} 

I want this to run for items starting from D to items starting F 
    @foreach (var item in Model.Items.OrderBy(i => i.Title)) 
     { 
// Code 
} 

任何幫助?

+0

如何處理主要數字(17「屏幕等)?是否被忽略(所以'17」屏幕將在'S'下排序或在'A'之前數字排序? – 2012-04-26 17:18:33

+0

它應該需要17 S:\ – Nanu 2012-04-26 17:35:34

回答

4

我將通過定義視圖模型(總是)開始:

public class MyViewModel 
{ 
    public string LetterRange { get; set; } 
    public string[] Titles { get; set; } 
} 

然後控制器操作將轉換從某處獲取模型,然後將其映射到視圖模型。

備註:在這個例子中,我將在控制器動作中放置模型和視圖模型之間的映射代碼,但通常這應該進入單獨的映射層。例如,如果您使用AutoMapper這可能是一個好地方。

所以:

public ActionResult Index() 
{ 
    // The model could be of any form and come from anywhere but 
    // the important thing is that at the end of the day you will have 
    // a list of titles here 
    var model = new[] 
    { 
     "17\" Screen", 
     "100GB HD", 
     "10788 Firewire", 
     "Lock Cable", 
     "Monitor", 
     "Mouse", 
     "Keyboard", 
     "USB" 
    }; 

    // Now let's map this domain model into a view model 
    // that will be adapted to the requirements of our view. 
    // And the requirements of this view is to group the titles 
    // in ranges of 3 letters of the alphabet 
    var viewModel = Enumerable 
     .Range(65, 26) 
     .Select((letter, index) => new 
     { 
      Letter = ((char)letter).ToString(), 
      Index = index 
     }) 
     .GroupBy(g => g.Index/3) 
     .Select(g => g.Select(x => x.Letter).ToArray()) 
     .Select(range => new MyViewModel 
     { 
      LetterRange = string.Format("{0}-{1}", range.First(), range.Last()), 
      Titles = model 
       .Where(item => item.Length > 0 && range.Contains(item.Substring(0, 1))) 
       .ToArray() 
     }) 
     .ToArray(); 

    // Let's add those titles that weren't starting with an alphabet letter 
    var other = new MyViewModel 
    { 
     LetterRange = "Other", 
     Titles = model.Where(item => !viewModel.Any(x => x.Titles.Contains(item))).ToArray() 
    }; 

    // and merge them into the final view model 
    viewModel = new[] { other }.Concat(viewModel).ToArray(); 

    return View(viewModel); 
} 

,現在所有剩下的在相應的視圖是按照要求來顯示標題:

@model MyViewModel[] 

@foreach (var item in Model) 
{ 
    <h2>@item.LetterRange</h2> 
    foreach (var title in item.Titles) 
    { 
     <div>@title</div> 
    } 
} 

和結果:

enter image description here


和重構映射邏輯到映射層之後,這裏的相應的控制器動作可能什麼樣子:

public ActionResult Index() 
{ 
    // The model could be of any form and come from anywhere but 
    // the important thing is that at the end of the day you will have 
    // a list of titles here 
    DomainModel[] items = ... 

    // Now let's map this domain model into a view model 
    // that will be adapted to the requirements of our view. 
    var viewModel = Mapper.Map<IEnumerable<DomainModel>, IEnumerable<MyViewModel>>(items); 

    return View(viewModel); 
} 

清潔和乾燥。

0

試試這個:

Model.Items.Sort((x, y)=> x.Title.CompareTo(y.Title)); 
foreach (var item in Model.Items.Where(x => x.Title[0] >= 'A' && x.Title[0] <= 'C') 
{ 
    //code 
} 
0

不知道這是最優雅的解決方案,但它會工作。我去看看我能想到的東西更好...

var itemsAtoC = Model.Items.Where.Where(i => i.StartsWith("A") || i.StartsWith("B") || i.StartsWith("C")); 

foreach(var item in itemsAtoC) 

{ 
    Console.Write(item); 
} 

Ugggh這並沒有真正處理NUMERICS要麼...

還在想......

+1

該代碼將返回一個非排序的枚舉數,因此雖然結果將被正確過濾,但它們將按插入列表的順序進行處理。 – pdriegen 2012-04-26 17:22:05

1

爲什麼不:

var fromAtoC = Model.Items.Where(x => x.Title != null && x.Title[0] >= 'A' && x.Title[0] <= 'C'); 

foreach(Model.Items m in fromAtoC) 
{ 
     //Do some stuff 
} 

var fromDtoF = Model.Items.Where(x => x.Title != null && x.Title[0] >= 'D' && x.Title[0] <= 'F'); 

for(Model.Items m in fromDtoF) 
{ 
     //Do some stuff 
}