Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Splitting a list into alphabetic ranges

Tags:

c#

list

I need to split a list into multiple lists that are grouped according to the first character of a string property. Here's an example.

class Program
{
    static void Main(string[] args)
    {
        var makes = new List<VehicleMake>
                        {
                            new VehicleMake {Name = "Acura"},
                            new VehicleMake {Name = "AMG"},
                            new VehicleMake {Name = "Audi"},
                            new VehicleMake {Name = "BMW"},
                            new VehicleMake {Name = "Chevrolet"},
                            new VehicleMake {Name = "Datsun"},
                            new VehicleMake {Name = "Eagle"},
                            new VehicleMake {Name = "Fiat"},
                            new VehicleMake {Name = "Honda"},
                            new VehicleMake {Name = "Infiniti"},
                            new VehicleMake {Name = "Jaguar"}
                        };

        var balancedLists = makes.Balance(new List<BalancedListGroup>
                          {
                              new BalancedListGroup { RangeStart = 'A', RangeEnd = 'C'},
                              new BalancedListGroup { RangeStart = 'D', RangeEnd = 'F'},
                              new BalancedListGroup { RangeStart = 'G', RangeEnd = 'J'},
                          });

        foreach (var balancedList in balancedLists)
        {
            foreach (var vehicleMake in balancedList)
            {
                Console.WriteLine(vehicleMake.Name);
            }
            Console.WriteLine("---");
        }
        Console.ReadLine();
    }
}

public class VehicleMake
{
    public string Name { get; set; }
}

public static class VehicleMakeListBalancer
{
    public static List<List<VehicleMake>> Balance(this List<VehicleMake> list, List<BalancedListGroup> groups)
    {
        var letters =
            new List<string> { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "y", "z" };
        var balancedLists = new List<List<VehicleMake>>();
        foreach (var group in groups)
        {
            var groupList = new List<VehicleMake>();
            for (var i = letters.IndexOf(group.RangeStart.ToString().ToLower()); i <= letters.IndexOf(group.RangeEnd.ToString().ToLower()); i++)
            {
                groupList.AddRange(list.Where(l => l.Name.ToLower().StartsWith(letters[i].ToString())).ToList());
            }
            balancedLists.Add(groupList);
        }

        return balancedLists;
    }
}

public class BalancedListGroup
{
    public char RangeStart { get; set; }
    public char RangeEnd { get; set; }
}

Which outputs:

Acura
AMG
Audi
BMW
Chevrolet
---
Datsun
Eagle
Fiat
---
Honda
Infiniti
Jaguar
---

This algorithm works, but feels very clumsy. Is there a more elegant way to do this?

like image 950
Craig M Avatar asked Apr 08 '11 17:04

Craig M


People also ask

How do you divide a list into parts?

Using a for loop and range() method, iterate from 0 to the length of the list with the size of chunk as the step. Return the chunks using yield . list_a[i:i+chunk_size] gives each chunk. For example, when i = 0 , the items included in the chunk are i to i + chunk_size which is 0 to (0 + 2)th index.

How do you split the alphabet into 5 groups?

Thus, the letters A, B, C, D will be in the first group, the letters E, F, G, H will. The English alphabet is divided into five groups. Each group starts with the vowel and the consonants immediately following that vowel and the consonants immediately following that vowel are included in that group.

How would you split a list into evenly sized chunks?

The easiest way to split list into equal sized chunks is to use a slice operator successively and shifting initial and final position by a fixed number.

Can you split a list element in Python?

To split the elements of a list in Python: Use a list comprehension to iterate over the list. On each iteration, call the split() method to split each string.


1 Answers

Following extention method uses linq to select all the vehicle makes whose name starts in range of characters.

        public static List<VehicleMake> GetInRange(this List<VehicleMake> vehicleList, char RangeStart, char RangeEnd)
        {
            var vehiclesInRange = from vm in vehicleList
                                  where vm.Name[0] >= RangeStart && vm.Name[0] <= RangeEnd
                                  select vm;

            return vehiclesInRange.ToList();
        }

USAGE SAMPLE

    static class Program
    {
        static void Main(string[] args)
        {
            var makes = new List<VehicleMake> { 
                new VehicleMake { Name = "Acura" },
                new VehicleMake { Name = "AMG" },
                new VehicleMake { Name = "Audi" }, 
                new VehicleMake { Name = "BMW" }, 
                new VehicleMake { Name = "Chevrolet" },
                new VehicleMake { Name = "Datsun" },
                new VehicleMake { Name = "Eagle" }, 
                new VehicleMake { Name = "Fiat" },
                new VehicleMake { Name = "Honda" }, 
                new VehicleMake { Name = "Infiniti" },
                new VehicleMake { Name = "Jaguar" } 
            }; 


            var atoc =  makes.GetInRange('A', 'C');
            atoc.Print();

            var dtom = makes.GetInRange('D', 'M');
            dtom.Print();

            var mtoz = makes.GetInRange('M', 'Z');
            mtoz.Print();

            Console.ReadLine();
        }

        static List<VehicleMake> GetInRange(this List<VehicleMake> vehicleList, char RangeStart, char RangeEnd)
        {
            var vehiclesInRange = from vm in vehicleList
                                  where vm.Name[0] >= RangeStart && vm.Name[0] <= RangeEnd
                                  select vm;

            return vehiclesInRange.ToList();
        }

        static void Print(this List<VehicleMake> vehicles)
        {
            Console.WriteLine();
            vehicles.ForEach(v => Console.WriteLine(v.Name));
        }
    }
like image 85
Sanjeevakumar Hiremath Avatar answered Sep 25 '22 16:09

Sanjeevakumar Hiremath