Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将一周中的几天列表分组为连续几天的组_C#_Collections_Grouping_Dayofweek_Nodatime - Fatal编程技术网

C# 将一周中的几天列表分组为连续几天的组

C# 将一周中的几天列表分组为连续几天的组,c#,collections,grouping,dayofweek,nodatime,C#,Collections,Grouping,Dayofweek,Nodatime,我正在使用C#创建一个函数,该函数包含一个NodaTime.IsoDayOfWeekdays的列表。我想将输入分组为连续几天的组 例如,以下列表应给出以下输出: { Mon, Tue } => { { Mon, Tue } } { Mon, Wed } => { { Mon }, { Wed } } { Mon, Tue, Fri, Sat } => { { Mon, Tue }, { Fri, Sat } } { Mon, Wed, Fri, Sun } => { {

我正在使用C#创建一个函数,该函数包含一个
NodaTime.IsoDayOfWeek
days的列表。我想将输入分组为连续几天的组

例如,以下列表应给出以下输出:

{ Mon, Tue } => { { Mon, Tue } }
{ Mon, Wed } => { { Mon }, { Wed } }
{ Mon, Tue, Fri, Sat } => { { Mon, Tue }, { Fri, Sat } }
{ Mon, Wed, Fri, Sun } => { { Sun, Mon }, { Wed }, { Fri } }
{ Mon, Tue, Wed, Thu, Fri, Sat, Sun } => { { Mon, Tue, Wed, Thu, Fri, Sat, Sun } }
请注意,星期日和星期一是连续的,因此列表是一个闭环。此外,结果列表的排序应确保第一天直接在输入列表中未包含的日期之后(如果包含完整列表,则为星期一)

公共静态IEnumerable组连续(此IEnumerable列表){
var group=新列表();
foreach(列表中的变量i){

如果(group.Count==0 | | i-group[group.Count-1]样本输入是按顺序排列的数组。假设您的输入是从1到7的数组,而不是按顺序排列的,您必须使用2个循环按条件查找下一个数字
Abs(当前下一个)==1 | Abs(当前下一个)==6
。 这是我对您的解决方案的想法:

public static IEnumerable<IEnumerable<int>> GroupDay(IEnumerable<int> list)
    {
        List<int> input = new List<int>(list);

        while (input.Count > 0)
        {
            int i = input[0];
            var group = new List<int>();
            group.Add(i);
            input.RemoveAt(0);

            for (int j = 0; j < input.Count; )
            {
                if (Math.Abs(group[group.Count - 1] - input[j]) == 1
                    || Math.Abs(group[0] - input[j]) == 6)
                {
                    group.Add(input[j]);
                    input.RemoveAt(j);
                }
                else
                {
                    j++;
                }
            }

            // Sort output
            group.Sort((x, y) => {
                if (Math.Abs(x - y) == 6)
                {
                    // Sunday and Monday case
                    return y - x;
                }
                else
                    return x - y;
            });
            yield return group;
        }
    }
公共静态IEnumerable组日(IEnumerable列表)
{
列表输入=新列表(列表);
while(input.Count>0)
{
int i=输入[0];
var group=新列表();
添加(i)组;
input.RemoveAt(0);
对于(int j=0;j{
如果(数学绝对值(x-y)==6)
{
//星期日及星期一个案
返回y-x;
}
其他的
返回x-y;
});
收益率-收益率组;
}
}

我并没有更有效地使用LINQ,但我认为这样可以。这只是一个简单的控制台应用程序

 public enum Days
        {
            Mon = 1,
            Tue,
            Wed,
            Thur,
            Fri,
            Sat,
            Sun
        }






public static IEnumerable<IEnumerable<int>> GroupDay(IEnumerable<int> ListOfDays)        
{
            List<List<int>> Response = new List<List<int>>();
            List<int> Queue = new List<int>();
            var ListToIterate = ListOfDays.Distinct().OrderBy(d => d).ToList();
            foreach (var item in ListToIterate)
            {

                if (Queue.Count == 0)
                {
                    Queue.Add(item);
                }
                else
                {
                    if ((item - 1) == Queue[Queue.Count - 1])
                    {
                        Queue.Add(item);
                    }
                    else if (item != (int)Days.Sun)
                    {
                        Response.Add(Queue);
                        Queue = new List<int>() { item };
                    }
                }

                if (item == ListToIterate.LastOrDefault())
                    Response.Add(Queue);

                //Handle Sunday
                if (item == (int)Days.Sun)
                {
                    //Check if Saturday exists, if exists then do not put sunday before Monday.
                    var FindSaturday = Response.Where(r => r.Contains((int)Days.Sat)).FirstOrDefault();
                    if (FindSaturday == null)
                    {
                        var FindMonday = Response.Where(r => r.Contains((int)Days.Mon)).FirstOrDefault();
                        if (FindMonday != null)
                        {
                            FindMonday.Insert(0, item);
                        }
                    }

                }

            }
            return Response;
        }
公共枚举天数
{
Mon=1,
星期二,
结婚,
星期四,
星期五,
坐,
太阳
}
公共静态IEnumerable GroupDay(IEnumerable ListOfDays)
{
列表响应=新列表();
列表队列=新列表();
var ListToIterate=ListOfDays.Distinct().OrderBy(d=>d.ToList();
foreach(ListToItem中的变量项)
{
如果(Queue.Count==0)
{
添加(项目);
}
其他的
{
如果((项-1)=队列[Queue.Count-1])
{
添加(项目);
}
else if(item!=(int)Days.Sun)
{
添加(队列);
队列=新列表(){item};
}
}
if(item==ListToIterate.LastOrDefault())
添加(队列);
//周日处理
if(item==(int)Days.Sun)
{
//检查周六是否存在,如果存在,则不要将周日放在周一之前。
var FindSaturday=Response.Where(r=>r.Contains((int)Days.Sat)).FirstOrDefault();
如果(FindSaturday==null)
{
var FindMonday=Response.Where(r=>r.Contains((int)Days.Mon)).FirstOrDefault();
如果(FindMonday!=null)
{
FindMonday.插入(0,项目);
}
}
}
}
返回响应;
}
下面是我如何尝试一些用例的

//List<int> ListOfDays = new List<int>() { DaysToNumber(Days.Mon), DaysToNumber(Days.Tue) };
            //List<int> ListOfDays = new List<int>() { DaysToNumber(Days.Mon), DaysToNumber(Days.Wed) };
            //List<int> ListOfDays = new List<int>() { DaysToNumber(Days.Mon), DaysToNumber(Days.Tue), DaysToNumber(Days.Fri), DaysToNumber(Days.Sat) };
            //List<int> ListOfDays = new List<int>() { DaysToNumber(Days.Mon), DaysToNumber(Days.Wed), DaysToNumber(Days.Fri), DaysToNumber(Days.Sun) };
            //List<int> ListOfDays = new List<int>() { DaysToNumber(Days.Mon), DaysToNumber(Days.Tue), DaysToNumber(Days.Wed), DaysToNumber(Days.Thur), DaysToNumber(Days.Fri), DaysToNumber(Days.Sat), DaysToNumber(Days.Sun) };
            List<int> ListOfDays = new List<int>() { DaysToNumber(Days.Mon),DaysToNumber(Days.Fri),  DaysToNumber(Days.Sun) };
            var ListToIterate = ListOfDays.Distinct().OrderBy(d => d).ToList();
            var result = GroupDay(ListToIterate);
//List ListOfDays=new List(){DaysToNumber(Days.Mon),DaysToNumber(Days.Tue)};
//List ListOfDays=new List(){DaysToNumber(Days.Mon),DaysToNumber(Days.Wed)};
//List ListOfDays=new List(){DaysToNumber(Days.Mon)、DaysToNumber(Days.Tue)、DaysToNumber(Days.Fri)、DaysToNumber(Days.Sat)};
//List ListOfDays=new List(){DaysToNumber(Days.Mon)、DaysToNumber(Days.Wed)、DaysToNumber(Days.Fri)、DaysToNumber(Days.Sun)};
//List ListOfDays=新列表(){DaysToNumber(Days.Mon)、DaysToNumber(Days.Tue)、DaysToNumber(Days.Wed)、DaysToNumber(Days.Thur)、DaysToNumber(Days.Fri)、DaysToNumber(Days.Sat)、DaysToNumber(Days.Sun)};
List ListOfDays=new List(){DaysToNumber(Days.Mon)、DaysToNumber(Days.Fri)、DaysToNumber(Days.Sun)};
var ListToIterate=ListOfDays.Distinct().OrderBy(d=>d.ToList();
var结果=GroupDay(ListToItem);

这是我最终使用的解决方案。我在这里使用了Linq,但是它可以很容易地重写,没有Linq。我还为此编写了大量的单元测试,如果您希望访问它们,请发表评论

using NodaTime;
using System.Collections.Generic;
using System.Linq;

namespace Domain.Extensions
{
    public static class IsoDayOfWeekExtensions
    {
        public static IReadOnlyList<IReadOnlyList<IsoDayOfWeek>> GroupConsecutive(this IList<IsoDayOfWeek> days)
        {
            var groups = new List<List<IsoDayOfWeek>>();
            var group = new List<IsoDayOfWeek>();

            var daysList = days.Distinct().OrderBy(x => (int)x);
            foreach (var day in daysList)
            {
                if (!group.Any() || (int)day - (int)group.Last() == 1)
                {
                    group.Add(day);
                }
                else
                {
                    groups.Add(group);
                    group = new List<IsoDayOfWeek>() { day };
                }
            }

            // Last group will not have been added yet. Check if the last group can be combined with the first group (Sunday and Monday are also consecutive!)
            if (group.Contains(IsoDayOfWeek.Sunday) && groups.Any() && groups.First().Contains(IsoDayOfWeek.Monday))
            {
                // Insert before the Monday so that the days are in the correct consecutive order.
                groups.First().InsertRange(0, group);
            }
            else
            {
                groups.Add(group);
            }

            return groups.Select(x => x.ToList()).ToList();
        }
    }
}
使用NodaTime;
使用System.Collections.Generic;
使用System.Linq;
命名空间域.扩展
{
公共静态类IsoDayOfWeekExtensions
{
公共静态IReadOnlyList组连续(此IList天)
{
变量组=新列表();
var group=新列表();
var daysList=days.Distinct().OrderBy(x=>(int)x);
foreach(var day in daysList)
{
如果(!group.Any()| |(int)day-(int)group.Last()==1)
{
加组(天);
}
其他的
{
组。添加(组);
组=新列表(){day};
}
}
//尚未添加最后一个组。请检查最后一个组是否可以与第一个组(Sun)组合
using NodaTime;
using System.Collections.Generic;
using System.Linq;

namespace Domain.Extensions
{
    public static class IsoDayOfWeekExtensions
    {
        public static IReadOnlyList<IReadOnlyList<IsoDayOfWeek>> GroupConsecutive(this IList<IsoDayOfWeek> days)
        {
            var groups = new List<List<IsoDayOfWeek>>();
            var group = new List<IsoDayOfWeek>();

            var daysList = days.Distinct().OrderBy(x => (int)x);
            foreach (var day in daysList)
            {
                if (!group.Any() || (int)day - (int)group.Last() == 1)
                {
                    group.Add(day);
                }
                else
                {
                    groups.Add(group);
                    group = new List<IsoDayOfWeek>() { day };
                }
            }

            // Last group will not have been added yet. Check if the last group can be combined with the first group (Sunday and Monday are also consecutive!)
            if (group.Contains(IsoDayOfWeek.Sunday) && groups.Any() && groups.First().Contains(IsoDayOfWeek.Monday))
            {
                // Insert before the Monday so that the days are in the correct consecutive order.
                groups.First().InsertRange(0, group);
            }
            else
            {
                groups.Add(group);
            }

            return groups.Select(x => x.ToList()).ToList();
        }
    }
}