2014-05-20 38 views
0

我有两个列表,我分配这种方式其中之一:如何在某些条件下在linq查询中分配两个列表?

var query = Enumerable.Range(0, 1440).Select((n, index) => 
{ 
    if ((index >= 525 && index <= 544) || (index >= 600 && index <= 749) || (index >= 810 && index <= 1079) || (index >= 1300 && index <= 1439)) 
     return 0; 
    else if (index >= 1080 && index <= 1299) 
     return 1; 
    else if (index >= 545 && index <= 599) 
     return 3; 
    else if (index >= 750 && index <= 809) 
     return 4; 
    else 
     return 2; 
}).ToList(); 

我的第二个名单被命名为LST2。我想根据我的第一个列表查询将其分配为“0”或“1”。因此,如果查询是“1”或“2”,则lst2的相同索引和先前索引是“0”值,应该是“1”。如果查询列表是“3”或“4”,则lst2的相同索引和先前的索引是“1”值,应该是“0”。另外,如果查询的第一个指示符的值为“3”或“4”,则lst2的相同指示符应为“0”。例如;

query = {3,3,3,0,0,0,2,2,0,0,0,0,4,4,4,4,0,0,0,0,1,1,1,0,0,2,2,0,0,4,4} 
lst2 = {0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0} 

我该怎么做?

编辑:如果查询的任何指数有3或4的值,lst2的同一个指标必须有0值。如果查询的任何指数具有3或4的值且前面的指数具有0值,则lst2的相同指数必须具有0值。同样地;如果查询的任何指数有1或2的值,lst2的相同指数必须有1个值。如果查询的任何指数具有1或2的值且前面的指数具有0值,则lst2的相同指数必须具有1个值。

+2

该列表中有1440个元素,在您的示例数据('query'和'lst2')中只显示一段摘录,是否正确?一般来说,如果指数(+以前的指数)如此重要,LINQ并不是最好的选择。使用'for'循环。 –

+0

是的。借调。使用for循环,并同时写入两个列表。从延迟执行或任何其他方面来看,linq并没有从中获得太多好处,所以不需要太依附它。 – Chris

+0

这是正确的。 lst2应该有相同的大小,这是一个摘录。我怎样才能说服自己? – 1teamsah

回答

1

的另一种方法,只需要填写当跟踪0。性能明智的是最好循环反转,但我只看到T_D已经这样做了,所以就前瞻 - >回顾而言,下面基本上是相同的,但是具有其他语法和不同的尾部填充符。

var arr = new int[query.Count]; 
    int cnt = query.Count - 1, toappendindex = -1; 
    Func<int,int,int> getval = (ind, val) => 
    { 
     if (val == 3 || val == 4) return 0; 
     if (val == 2 || val == 1) return 1; 
     if (ind == cnt) return -1; 
     return arr[ind + 1]; 
    }; 
    for (int ind = cnt; ind >= 0; ind--) 
    { 
     if ((arr[ind] = getval(ind,query[ind])) == -1) 
      toappendindex = ind; //only if there are trailing 0's 
    } 
    if (toappendindex > 0) 
     for (; toappendindex < arr.Length; toappendindex++) arr[toappendindex] = arr[toappendindex - 1]; 

    //var lst2 = arr.ToList(); if list is needed instead of array, otherwise arr could be used directly 
1

试着做这个。

 List<int> query = Enumerable.Range(0, 1440).Select((n, index) => 
     { 
      if ((index >= 525 && index <= 544) || (index >= 600 && index <= 749) || (index >= 810 && index <= 1079) || (index >= 1300 && index <= 1439)) 
       return 0; 
      else if (index >= 1080 && index <= 1299) 
       return 1; 
      else if (index >= 545 && index <= 599) 
       return 3; 
      else if (index >= 750 && index <= 809) 
       return 4; 
      else 
       return 2; 
     }).ToList(); 

     Console.WriteLine(string.Concat("{", string.Join(",", query.ToArray()), "}")); 

     List<int> lst2 = Enumerable.Range(0, 1440).Select((n, index) => 
     { 
      if (query[index] == 1 || query[index] == 2) 
       return 1; 
      else if (query[index] == 3 || query[index] == 4) 
       return 0; 
      else 
      { 
       int retval = 1; 
       //look ahead 
       for (int i = index; i < query.Count; i++) 
       { 
        if (query[i] == 1 || query[i] == 2) 
        { 
         break; 
        } 
        if (query[i] == 3 || query[i] == 4) 
        { 
         retval = 0; 
         break; 
        } 
       } 
       return retval; 
      } 
     }).ToList(); 

     Console.WriteLine(string.Concat("{", string.Join(",", lst2.ToArray()), "}")); 

让我知道这是你在找什么。如果你喜欢,你可以用List替换List。我只是喜欢它强类型,以便我可以轻松地检查输出。

+0

谢谢,但这不是我想要的。我已经用更多的细节修正了这个问题。 – 1teamsah

+0

那怎么样? – phoenixinobi

+0

我修改了代码来解释最后的0。 – phoenixinobi

1

我希望这是你所需要的:

int n = 1440; 
    byte[] query = new byte[n]; 
    byte[] lst2 = new byte[n]; 
    byte mode = 0; 
    bool first = true; 
    for(int index = n-1; index >= 0; index--) 
    { 

     if ((index >= 525 && index <= 544) || (index >= 600 && index <= 749) || (index >= 810 && index <= 1079) || (index >= 1300 && index <= 1439)) 
      query[index] = 0; 
     else if (index >= 1080 && index <= 1299) 
      query[index] = 1; 
     else if (index >= 545 && index <= 599) 
      query[index] = 3; 
     else if (index >= 750 && index <= 809) 
      query[index] = 4; 
     else 
      query[index] = 2; 

     if(query[index] == 3 || query[index] == 4) 
     { 
      mode = 0; 
      lst2[index] = 0; 
     } 
     else if(query[index] == 1 || query[index] == 2) 
     { 
      if(first) 
      { 
       //change ending zeros to 1 
       for(int j=index+1; j < n; j++) 
        lst2[j] = 1; 

       first = false; 
      } 
      mode = 1; 
      lst2[index] = 1; 
     } 
     else 
     { 
      lst2[index] = mode; 
     } 
    } 
+0

感谢您的回答。这有些错误地工作。例如;如果查询= {2,2,2,0,0,0,3,3,0,0,0,0,4,4,4,4,0,0,0,0,1,1,1, 0,0,0,0}则lst2应该是{1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1 ,1,1,1,1,1,1,1,1}。但是这个解决方案的结果是{1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1, 1,0,0,0,0}。可以做什么? – 1teamsah

+0

我不知道结尾零的规则。只是继续以前的模式? –

+0

你说得对。事实上;如果查询的第一个值不是0,那么lst2的相同索引应该是0.如果查询的最后一个值是0,那么lst2的相同索引应该是1.对不起,我想我没有说这个。 – 1teamsah

相关问题