Home > Back-end >  Sublists of consecutive elements that fit a condition in a list c# linq
Sublists of consecutive elements that fit a condition in a list c# linq

Time:12-15

So suppose we have a parking(represented as a dictionary<int,bool> : Every parking lot has its id and a boolean(free,filled). This way:

Dictionary<int,bool> parking..
parking[0]= true // means that the first parking lot is free

My question is i want to get the all sublist of consecutive elements that matchs in a condition : parking-lot is free.

First i can get elements that fits in this condition easy:

parking.Where(X => X.Value).Select(x => x.Key).ToList();

But then using linq operations i dont know how to get the first generated list that matchs in. Can i do this without thousand of foreach-while loops checking iterating one by one, is there a easier way with linq?

This method gets a list of consecutive free parking lots data: 0-free, 1-free, 2-filled , 3-free The results will be two lists: First One will contain => 0 ,1 Second One will contain=> 3 These are the list of consecutive of parking lots that are free.

public List<List<int>> ConsecutiveParkingLotFree(int numberOfConsecutive){}

CodePudding user response:

You can always write your own helper function to do things like this. For example

public static IEnumerable<List<T>> GroupSequential<T, TKey>(
    this IEnumerable<T> self,
    Func<T, bool> condition)
{
    var list = new List<T>();
    using var enumerator = self.GetEnumerator();
    if (enumerator.MoveNext())
    {
        var current = enumerator.Current;
        var oldValue = condition(current);
        if (oldValue)
        {
            list.Add(current);
        }
        while (enumerator.MoveNext())
        {
            current = enumerator.Current;
            var newValue = condition(current);
            if (newValue)
            {
                list.Add(current);
            }
            else if (oldValue)
            {
                yield return list;
                list = new List<T>();
            }
            oldValue = newValue;
        }

        if (list.Count > 0)
        {
            yield return list;
        }
    }
}

This will put all the items with a true-value in a list. When a true->false transition is encountered the list is returned and recreated. I would expect that there are more compact ways to write functions like this, but it should do the job.

CodePudding user response:

You can apply GroupWhile solution here.

parking.Where(X => X.Value)
.Select(x => x.Key)
.GroupWhile((x, y) => y - x == 1)
.ToList()
  • Related