【问题标题】:Alter a months list dynamically动态更改月份列表
【发布时间】:2018-09-25 10:39:16
【问题描述】:

我遇到了一个需求。 我从database 得到两个标志,即lastMonthNumberlastMonthName,它们的范围可以是1 to 12January to December。 现在我有一个要求,如果lastMonthName="March"lastMonthNumner=12,那么父list应该如下:

1, April
2, May
3, June
4, July
5, August
6, September
7, October
8, November
9, December
10, January
11, February
12, March

如果lastMonthName="April"lastMonthNumber=6,那么列表应该是:

7, November
8, December
9, January
10, February
11, March
12, April

这个lastMonthNumber 的范围可以是1 to 12lastMonthName 也可以是Jan to Dec。父 list 需要是动态的。

如果lastMonthNumber=6lastMonthName="April",则list 需要有 6 个元素,其中 April 为 12,并且回溯总共有 6 个元素。

list可以是dictionary,如:

var monthsDictionary=new Dictionary<int, string>();

我正在尝试以下操作,但无法进一步可视化:

var monthsDictionary = new Dictionary<int, string>();
var numbers = new List<int> { 1,2,3,4,5,6,7,8,9,10,11,12};
var months = new List<string> {"January","February","March","April","May","June","July","August","September","October","November","December" };
 foreach (var month in months.Select())
     {
         if (month == lastMonthName)
            {

            }
      }

请帮忙。指针会很有帮助。

【问题讨论】:

  • 在 lastMonthName="April" 和 lastMonthNumber=6 的示例中,您如何确定所有需要显示/返回的值?
  • 列表需要回溯。如果lastMonthNumber=6,则父列表需要有6个元素,如果lastMonthName=April,则需要从4月开始回溯有6个元素。希望它现在清除。
  • 所以你的意思是如果我们可以 lastMonthName = 'Oct' 和 lastMonthNumber = 2,那么结果将是11 - Sep, 12 - Oct??
  • @DeepakSharma 是的,你是对的。

标签: c# linq foreach


【解决方案1】:

有一个带有月份名称的常量

private readonly string[] monthNames = { "Januar" ..., "December" };

以及能够循环索引的访问器方法:

private string GetMonthName(int index)
{
  if (index < 0) return monthNames[monthNames.Length - 1 - (index % monthNames.Length)];
  return monthNames[index % monthNames.Length];
}

然后创建列表:

int indexOfLastMonthName = Array.IndexOf(monthNames, lastMonthName);

var parentData = Enumerable
  // Create as many items as last month number
  .Range(0, lastMonthNumber)

  // Create the list in reverse order, start on LastMonthName and 12,
  // then go back with every item
  .Select(x => new 
  { 
    Number = 12 - x, 
    Name = GetMonthName(indexOfLastMonthName - x)
  }

  // Turn it back
  .Reverse();

然后将其填充到适当的数据结构中。例如像这样:

List<Tuple<int, string>> parentList = parentData
  .Select(x => Tuple.Create(x.Number, x.Name)))
  .ToList();

如果您更喜欢经典解决方案(使用上面的 GetMonthName 方法):

int indexOfLastMonthName = Array.IndexOf(monthNames, lastMonthName);
List<Tuple<int, string>> parentList = new List<Tuple<int, string>>();

for(int i = 0; i < lastMonthNumber; i++)
{
  parentList.Add(
    Tuple.Create(
      12 - i, 
      GetMonthName(indexOfLastMonthName - i));
}

parentList.Reverse();

【讨论】:

  • IndexOf 不只接受 1 个参数。
  • 好的,这是一个数组。我应该使用Array.IndexOf - 已修复。
  • 我修复了一些小问题。
  • 谢谢..我去看看。
【解决方案2】:

试试这个 linq 查询

var months = new List<string> {"January","February","March","April","May","June","July","August","September","October","November","December" };

var lastMonthNumber = ...;
var lastMonthName = ....;

var rows = months.Concat(months)
    .Reverse()
    .SkipWhile(m => m != lastMonthName)
    .Take(lastMonthNumber)
    .Reverse()
    .Select((m, i) => new { id = i + 12 - lastMonthNumber + 1, m})
    .ToArray();

它复制了一个月份列表,反转它并跳过项目,直到找到lastMonthName。之后,此代码限制结果项计数为 lastMonthNumber 并反向列出

【讨论】:

    【解决方案3】:

    试试下面的小提琴。 https://dotnetfiddle.net/GYP2Go

    private static Dictionary<int, string> GetRequiredResult(int lastMonthNumber, string lastMonthName)
    {
        var indx =  months.IndexOf(lastMonthName);
    
        // here this list will have months in required order that ends with lastMonthName
        var revisedMonthList = new List<string>();
        revisedMonthList.AddRange(months.Skip(indx + 1).Take(12));
        revisedMonthList.AddRange(months.Take(indx + 1));
    
        // get count = lastMonthNumber element from last using index, and then convert them to dictionary.
        return revisedMonthList
            .Select((mn, index) => new {index, mn})
            .Where(c => c.index >= months.Count - lastMonthNumber)
            .ToDictionary(c=>c.index + 1, c=>c.mn); 
    }
    

    【讨论】:

    • 我会尝试代码并通知您。谢谢。
    • 如果数据实际上是一个序列(列表)并且不希望按月数访问,我不会使用字典。
    • @StefanSteinegger,由于提到了OP,从List返回字典,返回响应可以是的字典
    【解决方案4】:
        var monthsDictionary = new Dictionary<int, string>();
        var numbers = new List<int> { 1,2,3,4,5,6,7,8,9,10,11,12};
        var months = new List<string> {"January","February","March","April","May","June","July","August","September","October","November","December" };
    int flag=0;
    int items=12;
    var numbersList = new List<int>();
    var monthsList = new List<string>(); 
         foreach (var month in months)
             {
                if(flag==0){
                 monthsList.Insert(items--,month);
                 if (month == lastMonthName)
                    {
                        flag=1;
                    }
    }
             else if(flag==1)
             {
               monthsList.add(month);
              }
              }
    flag=0;
    

    【讨论】:

    • 对号码列表执行相同的步骤,然后您可以将其添加到您的字典对象中
    • 我会尝试代码并通知您。谢谢。
    【解决方案5】:

    尝试以下:

            var months = Enumerable.Range(1, 12).Select(i => new
            {
                I = i,
                M = System.Globalization.DateTimeFormatInfo.CurrentInfo.GetMonthName(i)
            });
    
            //string lastMonthName = "March"; int lastMonthNumber = 12;
            //string lastMonthName = "April"; int lastMonthNumber = 6;
            var selMonthInt = months.Where(x => x.M == lastMonthName).Select(y => y.I).FirstOrDefault();
            int endCount = lastMonthNumber + selMonthInt;
            if (endCount >= 12) { endCount = selMonthInt; }
    
            var lst1 = months.Where(x => x.I > endCount).Select(z => z.M);
            var lst2 = months.Where(x => x.I <= selMonthInt).Select(z => z.M);
            var lst = lst1.Union(lst2).ToArray();
    
            var selMonths = Enumerable.Range(0, lastMonthNumber).Select(i => new { I = (13 - lastMonthNumber + i), M = lst[i] });
    

    【讨论】:

      猜你喜欢
      • 2019-08-10
      • 1970-01-01
      • 2019-05-29
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 2021-10-04
      • 2017-09-13
      相关资源
      最近更新 更多