views:

472

answers:

3

Hi all I trying to implement alpha ordered list by columns

as shown on picture

But my algorithm is not clear and maybe someone could help me within

string[] letters = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I",
  "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
  "Y", "Z", "Å", "Ä", "Ö", "0-9" };

int j = 0, s = 0, i = 1;
var fullServices = (from se in EntityBase.db.Services
               orderby se.Name
               select se).ToList();
int total = fullServices.Count;
var grouped = (from l in letters
            select new ServiceInfo
            {
              Letter = l,
              Services = EntityBase.db.Services.Where(se => se.Name.StartsWith(l)).ToList(),
              Total = EntityBase.db.Services.Where(se => se.Name.StartsWith(l)).Count()
            }).ToList();
Dictionary<int, List<ServiceInfo>> result = new Dictionary<int, List<ServiceInfo>>();

changecell:

List<ServiceInfo> item = new List<ServiceInfo>();
while (j < letters.Count())
{
letterchange:
   List<Service> _services = new List<Service>();
   while (s < total)
   {
      if ((s == (5 + (total % 5 > i ? 1 : 0)) * i))
      {
         item.Add(new ServiceInfo() { Letter = letters[j], Services = _services });
         result.Add(i, item);
         if (i == 6)
            goto exit;
         i++;
         goto changecell;
      }
      //start render services
      if (fullServices.ElementAt(s).Name.StartsWith(letters[j]))
      {
         _services.Add(fullServices.ElementAt(s));
         s++;//increment service in list
      }
      else //letter switch
      {
         item.Add(new ServiceInfo() { Letter = letters[j], Services = _services });
         j++;
         goto letterchange;
      }
   }//end render services

}
exit:
return View(result);

In a result of my code I see missed letters X Y Z Å Ä Ö and it's looks like this

Here comes code that renders dictionary

<% foreach (KeyValuePair<int, List<BL.Models.Infos.ServiceInfo>> col in Model)
{ %>
  <ul class="col">
    <% foreach (var item in col.Value)
 { %>
    <% if (!item.Services.Any())
 {%>
    <li class="disabled">
      <h1>
        <%= item.Letter %></h1>
    </li>
    <%}
 else
 { %>
    <li>
      <h1>
        <a href="/service/info/<%= item.Letter %>"><%= item.Letter %></a>
      </h1>
    </li>
    <% foreach (var service in item.Services)
 { %>
    <li><a href="/service/info/<%= service.Name %>"><%= service.Name %></a></li>
    <%}
 }
 }%>
  </ul>
  <%} %>

Please help...

+4  A: 

Well, you're certainly right that the code's not particularly clear :)

I don't really follow the main loop of your code, but here's a simpler starting point. Note that it won't group 0-9 properly (it only deals with 0 at the moment): I'm not sure the best way to approach that, to be honest. You might want to put that off until you get some entries which don't match any of the normal letters...

using System;
using System.Linq;

class Test
{   
    static void Main(string[] args)
    {
        ShowGroups();
    }

    private static readonly char[] Letters = 
        "ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ0".ToCharArray();

    // This is taking the place of EntityBase.db.Services
    // for the purposes of the test program
    public static string[] Services = { "Blogger", "Delicious", 
            "Digg", "Ebay", "Facebook", "Feed", "Flickr", 
            "Friendfeed", "Friendster", "Furl", "Google", 
            "Gosupermodel", "Lastfm", "Linkedin", "Livejournal",
            "Magnolia", "Mixx", "Myspace", "NetOnBuy", "Netvibes",
            "Newsvine", "Picasa", "Pownce", "Reddit", "Stumbleupon",
            "Technorati", "Twitter", "Vimeo", "Webshots", 
            "Wordpress" };

    public static void ShowGroups()
    {
        var groupedByLetter = 
            from letter in Letters
            join service in Services on letter equals service[0] into grouped
            select new { Letter = letter, Services = grouped };

        // Demo of how to access the groups
        foreach (var entry in groupedByLetter)
        {
            Console.WriteLine("=== {0} ===", entry.Letter);
            foreach (var service in entry.Services)
            {
                Console.WriteLine ("  {0}", service);
            }
            Console.WriteLine();
        }
    }
}

I don't know how you intend to split the results into 5 equal columns though...

Jon Skeet
A: 

This might be way off - I've just done this in Notepad (don't have access to an IDE right now). It looks like you're trying to populate the Dictionary<int, List<ServiceInfo>> result instance and I'm assuming that your View method understands how to layout the results in columns.

Here goes:

string[] letters = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
                                  "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
                                  "U", "V", "W", "X", "Y", "Z", "Å", "Ä", "Ö", "0-9" };

var result = new Dictionary<int, List<ServiceInfo>>();
foreach (var letter in letters)
{
    var services = (from se in EntityBase.db.Services
                    where se.Name.StartsWith(letter)
                    orderby se.Name
                    select select new ServiceInfo
                    {
                        Letter = letter,
                        Services = EntityBase.db.Services.Where(se => se.Name.StartsWith(letter)).ToList(),
                        Total = EntityBase.db.Services.Where(se => se.Name.StartsWith(letter)).Count()
                    }).ToList();
    result.Add(i, services);
}

If it's correct, it probably won't be the fastest implementation, but it's more readable.

dariom
Yeah, I have updated post and include code that belongs to renderBut still is problematic to create separation by columns I looked closer to code that *Jon Skeet* posted and it's doesn't help in final I made all this *goto's* just for separation. How create list with letters and services underneath I know...
omoto
A: 

Thanks everybody, but splinting of grouped list on equal columns is still problem for me...

omoto
Here comes solution http://stackoverflow.com/questions/930013/how-to-create-list-splitted-by-columns
omoto