[英]How to populate two separate arrays from one comma-delimited list?
我有一个逗号分隔的文本文件,其中包含由逗号分隔的20位数字。 这些数字代表10个不同作业的获得积分和可能积分。 我们将使用它们来计算课程的最终分数。
通常情况下,我会迭代数字,创建两个总和,除以并完成它。 但是,我们的任务规定我们将数字列表加载到两个数组中。
所以这:
10,10,20,20,30,35,40,50,45,50,45,50,50,50,20,20,45,90,85,85
成为这个:
int[10] earned = {10,20,30,40,45,50,20,45,85};
int[10] possible = {10,20,35,50,50,50,20,90,85};
现在,我正在使用
for (x=0;x<10;x++)
{
earned[x] = scores[x*2]
poss [x] = scores[(x*2)+1]
}
这给了我想要的结果,但看起来过于笨重。
有没有更好的办法?
以下内容应将列表中的每个交替项目拆分为另外两个列表。
int[20] scores = {10,10,20,20,30,35,40,50,45,50,45,50,50,50,20,20,45,90,85,85};
int[10] earned;
int[10] possible;
int a = 0;
for(int x=0; x<10; x++)
{
earned[x] = scores[a++];
possible[x] = scores[a++];
}
你可以在这里使用LINQ:
var arrays = csv.Split(',')
.Select((v, index) => new {Value = int.Parse(v), Index = index})
.GroupBy(g => g.Index % 2,
g => g.Value,
(key, values) => values.ToArray())
.ToList();
接着
var earned = arrays[0];
var possible = arrays[1];
摆脱“神奇”的乘法和难以辨认的数组索引计算。
var earned = new List<int>();
var possible = new List<int>();
for (x=0; x<scores.Length; x += 2)
{
earned.Add(scores[x + 0]);
possible.Add(scores[x + 1]);
}
这很少需要文本评论。 这是自我记录代码的黄金标准。
我最初认为问题是一个C问题,因为所有不可理解的索引。 它看起来像指针魔术。 太聪明了。
在我的代码库中,我通常有一个AsChunked
扩展,可以将列表拆分为给定大小的块。
var earned = new List<int>();
var possible = new List<int>();
foreach (var pair in scores.AsChunked(2)) {
earned.Add(pair[0]);
possible.Add(pair[1]);
}
现在代码的含义是显而易见的。 魔力消失了。
更短:
var pairs = scores.AsChunked(2);
var earned = pairs.Select(x => x[0]).ToArray();
var possible = pairs.Select(x => x[1]).ToArray();
我想你可以这样做:
int[] earned = new int[10];
int[] possible = new int[10];
int resultIndex = 0;
for (int i = 0; i < scores.Count; i = i + 2)
{
earned[resultIndex] = scores[i];
possible[resultIndex] = scores[i + 1];
resultIndex++;
}
您必须确保在scores
中存储相同数量的值。
我会保留你的代码。 从技术上讲,您非常直接地表达了您的意图,每个第二个元素都会进入每个数组。
改进该解决方案的唯一方法是评论您为什么成倍增加。 但我希望有人能够快速识别这个技巧,或者轻松地重现它正在做的事情。 这是一个如何评论的过多例子。 我不建议直接使用它。
for (x=0;x<10;x++)
{
//scores contains the elements inline one after the other
earned[x] = scores[x*2] //Get the even elements into earned
poss [x] = scores[(x*2)+1] //And the odd into poss
}
但是,如果您真的不喜欢乘法,则可以单独跟踪分数索引。
int i = 0;
for (int x = 0; x < 10; x++)
{
earned[x] = scores[i++];
poss [x] = scores[i++];
}
但我可能更喜欢你的版本,因为它不依赖于操作的顺序。
var res = grades.Select((x, i) => new {x,i}).ToLookup(y=>y.i%2, y=>y.x)
int[] earned = res[0].ToArray();
int[] possible = res[1].ToArray();
这将根据索引将所有等级分组为两个桶,如果需要数组形式的结果,则可以执行ToArray
。
这是我的评论示例,因此无论列表大小如何,您都无需更改代码:
ArrayList Test = new ArrayList { "10,10,20,20,30,35,40,50,45,50,45,50,50,50,20,20,45,90,85,85" };
int[] earned = new int[Test.Count / 2];
int[] Score = new int[Test.Count / 2];
int Counter = 1; // start at one so earned is the first array entered in to
foreach (string TestRow in Test)
{
if (Counter % 2 != 0) // is the counter even
{
int nextNumber = 0;
for (int i = 0; i < Score.Length; i++) // this gets the posistion for the next array entry
{
if (String.IsNullOrEmpty(Convert.ToString(Score[i])))
{
nextNumber = i;
break;
}
}
Score[nextNumber] = Convert.ToInt32(TestRow);
}
else
{
int nextNumber = 0;
for (int i = 0; i < earned.Length; i++) // this gets the posistion for the next array entry
{
if (String.IsNullOrEmpty(Convert.ToString(earned[i])))
{
nextNumber = i;
break;
}
}
earned[nextNumber] = Convert.ToInt32(TestRow);
}
Counter++
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.