使用LINQ在List<;T>;并添加整数以填充新的List<;T>;

本文关键字:lt gt List 填充 整数 添加 使用 LINQ | 更新日期: 2023-09-27 18:28:22

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

我想根据上一个列表中的第一个数字创建一个新的列表,它应该有相同数量的元素。我会在第一个数字上添加一个特定的数字,以此类推。例如,使用6作为要添加的数字,我会得到20,26,32。生成的列表将是list。数字6是一个类范围的属性。

如果我有一个"N"、"N"answers"32"的列表,问题就会出现

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

如果我有"N"、"26"、"N",我就必须用中间的数字来计算其他数字。

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

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

我想知道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

使用LINQ在List<;T>;并添加整数以填充新的List<;T>;

这样的东西怎么样:

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);

听起来你想要一个能的函数

  • 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;
}

出于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;
}

做一些简单的事情似乎需要做很多工作。这是一种非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;
    }

DevGeezer的答案,但没有cruft。但我还是学到了很多!

    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();
    }