使用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
这样的东西怎么样:
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();
}