-1

I want to split my list by value, but I don't need group the result, this is my list :

var source = new List<Car>() {
    new Car() { ID = 1, Model = "Model A" },
    new Car() { ID = 2, Model = "Model B" },
    new Car() { ID = 3, Model = "Model B" },
    new Car() { ID = 4, Model = "Model B" },
    new Car() { ID = 5, Model = "Model A" },
    new Car() { ID = 6, Model = "Model A" }
};
var result = GetListOfAdjacentCarsOfSameModel();

I want the resulting list to look like this:

- Model A
    - ID = 1, Model = "Model A"
- Model B
    - ID = 2, Model = "Model B"
    - ID = 3, Model = "Model B"
    - ID = 4, Model = "Model B" 
- Model A   
    - ID = 5, Model = "Model A"
    - ID = 6, Model = "Model A"
onlyme
  • 21
  • 4

3 Answers3

1

I suggest a simple loop:

var result = new List<List<Car>>();

foreach (var item in source)
  if (result.Count <= 0 || result[result.Count - 1][0].Model != item.Model)
    result.Add(new List<Car>() {item}); // Create a new group, add item to it
  else
    result[result.Count - 1].Add(item); // Add item into the last group
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
0
public class Car
{
    public int ID { get; set; }
    public string Model { get; set; }
}

public class Result
{
    public string Model { get; set; }
    public int Count { get; set; }
}


var source = new List<Car>();
source.Add(new Car { ID = 1, Model = "Model A" });
source.Add(new Car { ID = 1, Model = "Model B" });
source.Add(new Car { ID = 1, Model = "Model B" });
source.Add(new Car { ID = 1, Model = "Model B" });
source.Add(new Car { ID = 1, Model = "Model A" });
source.Add(new Car { ID = 1, Model = "Model A" });

var result = new List<Result>();
if (source.Any())
{
    string model = source[0].Model;
    int count = 0;
    foreach (var car in source)
    {
        if (car.Model == model)
        {
            count++;
        }
        else
        {
            result.Add(new Result { Model = model, Count = count });
            model = car.Model;
            count = 1;
        }
    }
    result.Add(new Result { Model = model, Count = count });
}

foreach (var r in result)
{
    Console.WriteLine(r.Model + " - " + r.Count);
}
Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49
0

I'm struggling with finding a simple way to do this, but you can always do it iteratively:

var source = new List<string>() {
    "Model A",
    "Model B",
    "Model B",
    "Model B",
    "Model A",
    "Model A"
};

string lastModel = null;
List<string> currentList = new List<string>();
var result = new List<List<string>>();

foreach (var model in source)
{
    if (lastModel != null && model != lastModel)
    {
        result.Add(currentList);
        currentList = new List<string>();
    }
    currentList.Add(model);
    lastModel = model;
}

if (currentList.Any()) {
    result.Add(currentList);
}

Now, it's easy to wrap that code in an extension method you can use on your car class:

var source = new List<Car>() {
    new Car { Model = "Model A" },
    new Car { Model = "Model B" },
    new Car { Model = "Model B" },
    new Car { Model = "Model B" },
    new Car { Model = "Model A" },
    new Car { Model = "Model A" }
};

var result = source.CollectAdjacentWithSameModel();

// elsewhere    
public static class EnumerableExtensions
{
    public static IEnumerable<IEnumerable<Car>> CollectAdjacentWithSameModel(this IEnumerable<Car> source)
    {
        var lastModel = default(Car);
        List<Car> currentList = new List<Car>();
        var result = new List<List<Car>>();

        foreach (var model in source)
        {
            if (lastModel != null && model.Model != lastModel.Model)
            {
                result.Add(currentList);
                currentList = new List<Car>();
            }
            currentList.Add(model);
            lastModel = model;
        }

        if (currentList.Any())
        {
            result.Add(currentList);
        }

        return result;
    }
}

public class Car {
    public string Model { get; set; }
}
Tomas Aschan
  • 58,548
  • 56
  • 243
  • 402