繁体   English   中英

如何从一个以逗号分隔的列表中填充两个单独的数组?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM