使用LINQ选择List <t>中的项目并添加整数以填充新List <t> </t> </t>

时间:2012-03-19 19:38:19

标签: c# .net linq

假设我有List<string> = new List<string>() {"20","26","32"}

我想根据前一个列表中的第一个数字创建一个新的List,它应该包含相同数量的元素。我将为第一个数字添加一定数量,依此类推。例如,使用6作为要添加的数字,我将获得20,26,32。结果列表将是List。 6号是一个广泛的属性。

如果我有一个“N”,“N”,“32”

列表,问题就来了

我需要生成相同的20,26,32列表,但我必须使用最后一个数字来计算其他数字。

如果我有“N”,“26”,“N”,我将不得不使用中间数来计算其他数字。

N表示输入列表中没有数据,它始终是此字符

总之,我需要生成一个与输入列表具有相同元素数量的新列表,并且必须使用第一个或下一个数字元素来生成结果列表,使用指定的数字来添加/减去值。 / p>

我想知道LINQ的聚合函数是否能够处理它但是使用它有点丢失。

示例:

"20","26","32" = 20,26,32
"N","26","32" = 20,26,32
"N","N","32" = 20,26,32
"20","26","N" = 20,26,32

5 个答案:

答案 0 :(得分:3)

听起来你想要一个

的功能
  • List<int>作为输入
  • 将原始列表的第一个元素作为新列表的第一个元素
  • 新列表与原始列表具有相同数量的元素
  • 剩余数字是第一个元素+值*位置

如果是,请尝试以下

static bool TryGetFirstNumber(List<string> list, out number, out index) {
  for (var i = 0; i < list.Count; i++) {
    var cur = list[0];
    if (!String.IsNullOrEmpty(cur) && Int32.TryParse(cur, out number)) {
      index = i;
      return true;
    }
  }
  number = 0;
  index = 0;
  return false;
}

static List<T> TheFunction(List<string> list, int increment) {
  var newList = new List<int>();
  int first;
  int index;
  if (TryGetFirstNumber(list, out first, out index)) {
    first -= index * increment;
  } else {
    first = 0;
  }

  newList.Add(first);
  for (var i = 1; i < list.Length; i++) {
    newList.Add(first + increment);
    increment += increment;
  }

  return newList;
}

答案 1 :(得分:3)

这样的事情:

var n = 6;

List<string> strList = new List<string>() {"20","26","32"}; 
// list can also be {null, "26", null} , {null, "N", "32"} , 
//                  {"N", "26", null } etc...

var list = strList.Select(s =>
{
   int v;
   if(string.IsNullOrEmpty(s) || !int.TryParse(s,out v))
      return (int?)null;
   return v;
});

var firstValidVal = list.Select((Num, Index) => new { Num, Index })
                        .FirstOrDefault(x => x.Num.HasValue);
if(firstValidVal == null)
    throw new Exception("No valid number found");

var bases = Enumerable.Range(0, strList.Count).Select(i => i * n);
int startVal = firstValidVal.Num.Value - bases.ElementAt(firstValidVal.Index);

var completeSequence = bases.Select(x => x + startVal);

答案 2 :(得分:2)

对于LINQ目的,我有时会尝试编写一个解析方法,该方法返回int?作为结果,以便在无法解析时返回null。这是一个完整的LINQPad实现,说明了这一点和位置选择(采用与digEmAll类似的方法):

void Main()
{
    var n = 6;
    var items = new List<string>
    //    {"20","N", "N"};
    //    {"N", "26", "N"};
        {"N", "N", "32"};

    var first = items
        .Select((v,index) => new { val = Parse(v), index })
        .First(x => x.val.HasValue);

    int start = first.val.Value - n * first.index;

    List<string> values = items
        .Select((x,i) => (i * n + start).ToString())
        .ToList();
}

int? Parse(string strVal)
{
    int ret;
    if (int.TryParse(strVal, out ret))
    {
        return ret;
    }
    return null;
}

答案 3 :(得分:1)

似乎做了很多简单的工作。这是一种非linq方法。

    private List<int> getVals(List<string> input, int modifier)
    {
        if (input == null) return null; if (input.Count < 1) return null;
        foreach (var s in input)
        {
            int i;
            try{i = Convert.ToInt32(s);}
            catch{continue;}
            var returnList = new List<int>(input.Count);
            for (int n = 0; n < input.Count;n++ )returnList[n] = ((n - input.IndexOf(s)) * modifier) + i;
            return returnList;
        }
        return null;
    }

答案 4 :(得分:0)

DevGeezer的答案,但没有任何瑕疵。 但我还是学到了很多东西!

    static List<String> genlist2(List<String> list, int interval)
    {
        if (list == null) return null;

        var vali = list
            .Select((x, i) => x != "N" ? new {val = Convert.ToInt32(x), i } : null)
            .First(x => x != null);

        if (vali == null) return list.ToList();

        return Enumerable.Range(0, list.Count)
            .Select(x => (vali.val - (vali.i - x) * interval).ToString())
            .ToList();
    }