简体   繁体   English

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

[英]How to populate two separate arrays from one comma-delimited list?

I have a comma delimited text file that contains 20 digits separated by commas. 我有一个逗号分隔的文本文件,其中包含由逗号分隔的20位数字。 These numbers represent earned points and possible points for ten different assignments. 这些数字代表10个不同作业的获得积分和可能积分。 We're to use these to calculate a final score for the course. 我们将使用它们来计算课程的最终分数。

Normally, I'd iterate through the numbers, creating two sums, divide and be done with it. 通常情况下,我会迭代数字,创建两个总和,除以并完成它。 However, our assignment dictates that we load the list of numbers into two arrays. 但是,我们的任务规定我们将数字列表加载到两个数组中。

so this: 所以这:

10,10,20,20,30,35,40,50,45,50,45,50,50,50,20,20,45,90,85,85

becomes this: 成为这个:

int[10] earned   = {10,20,30,40,45,50,20,45,85};
int[10] possible = {10,20,35,50,50,50,20,90,85};

Right now, I'm using 现在,我正在使用

for (x=0;x<10;x++)
{
     earned[x] = scores[x*2]
     poss  [x] = scores[(x*2)+1]
}

which gives me the results I want, but seems excessively clunky. 这给了我想要的结果,但看起来过于笨重。

Is there a better way? 有没有更好的办法?

The following should split each alternating item the list into the other two lists. 以下内容应将列表中的每个交替项目拆分为另外两个列表。

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++];
}

You can use LINQ here: 你可以在这里使用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();

and then 接着

var earned = arrays[0];
var possible  = arrays[1];

Get rid of the "magic" multiplications and illegible array index computations. 摆脱“神奇”的乘法和难以辨认的数组索引计算。

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

This has very little that would need a text comment. 这很少需要文本评论。 This is the gold standard for self-documenting code. 这是自我记录代码的黄金标准。

I initially thought the question was a C question because of all the incomprehensible indexing. 我最初认为问题是一个C问题,因为所有不可理解的索引。 It looked like pointer magic. 它看起来像指针魔术。 It was too clever. 太聪明了。

In my codebases I usually have an AsChunked extension available that splits a list into chunks of the given size. 在我的代码库中,我通常有一个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]);
}

Now the meaning of the code is apparent. 现在代码的含义是显而易见的。 The magic is gone. 魔力消失了。

Even shorter: 更短:

var pairs = scores.AsChunked(2);
var earned = pairs.Select(x => x[0]).ToArray();
var possible = pairs.Select(x => x[1]).ToArray();

I suppose you could do it like this: 我想你可以这样做:

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

You would have to be sure that an equal number of values are stored in scores . 您必须确保在scores中存储相同数量的值。

I would leave your code as is. 我会保留你的代码。 You are technically expressing very directly what your intent is, every 2nd element goes into each array. 从技术上讲,您非常直接地表达了您的意图,每个第二个元素都会进入每个数组。

The only way to improve that solution is to comment why you are multiplying. 改进该解决方案的唯一方法是评论您为什么成倍增加。 But I would expect someone to quickly recognize the trick, or easily reproduce what it is doing. 但我希望有人能够快速识别这个技巧,或者轻松地重现它正在做的事情。 Here is an excessive example of how to comment it. 这是一个如何评论的过多例子。 I wouldn't recommend using this directly. 我不建议直接使用它。

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
}

However if you really don't like the multiplication, you can track the scores index separately. 但是,如果您真的不喜欢乘法,则可以单独跟踪分数索引。

int i = 0;
for (int x = 0; x < 10; x++)
{
    earned[x] = scores[i++];
    poss  [x] = scores[i++];
}

But I would probably prefer your version since it does not depend on the order of the operations. 但我可能更喜欢你的版本,因为它不依赖于操作的顺序。

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

This will group all grades into two buckets based on index, then you can just do ToArray if you need result in array form. 这将根据索引将所有等级分组为两个桶,如果需要数组形式的结果,则可以执行ToArray

here is an example of my comment so you do not need to change the code regardless of the list size: 这是我的评论示例,因此无论列表大小如何,您都无需更改代码:

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