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