0

アイテムのリストがあるとしましょう

-17"画面 -100GBHD
- 10788Firewire- ロックケーブル- モニター- マウス -キーボード-USB





Aからc、DからFなどの項目のリストを繰り返したい...

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
}

ヘルプはありますか?

4

4 に答える 4

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

そして結果:

ここに画像の説明を入力してください


そして、マッピングロジックをマッピングレイヤーにリファクタリングした後、対応するコントローラーアクションは次のようになります。

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

きれいにして乾かします。

于 2012-04-26T18:17:11.003 に答える
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
}
于 2012-04-26T17:20:05.930 に答える
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);
}

うーん、これも実際には数値を扱っていません...

まだ考えています...

于 2012-04-26T17:15:48.070 に答える
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
}
于 2012-04-26T17:13:54.140 に答える