我正在尝试将文件读入全局数组,遍历数组并将每个字符串标识为相应的数量,然后在自己的组中找到总和。并按照自己唯一的数字划分这些群体。
我正在阅读的文本文件:
Name,50
Name,40
DifferentName,50
AnotherName,10
Name,60
在逗号分割行的最简单方法是什么,并使数字与其特定名称相对应,而不知道它们将在哪个顺序?
这是我到目前为止使用的代码。尽管现在它只是打开文件对话框,我把它放在这里作为建设性参考。
string strFileName;
private void btnReadInFile_Click(object sender, EventArgs e)
{
//select the file
OpenFileDialog ofdGetFile = new OpenFileDialog();
if (ofdGetFile.ShowDialog() == DialogResult.Cancel)
{
//cancel
MessageBox.Show("User Canceled");
return;
}
else
{
//open the file
StreamReader myStreamReader;
strFileName = ofdGetFile.FileName;
FileStream input = new FileStream(strFileName, FileMode.Open, FileAccess.Read);
myStreamReader = new StreamReader(input);
// other
MessageBox.Show("Reading Complete", "Done!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void btnShowGrade_Click(object sender, EventArgs e)
{
if (strFileName != null)
{
String[][] nameSums = System.IO.File.ReadLines(strFileName)
.Select(l => l.Split(',')) // split the line
.GroupBy(arr => arr[0]) // group by name
.Select(grp => new String[]{
grp.Key,
grp.Sum(arr => int.Parse(arr[1])).ToString()})
.ToArray();
}
else
{
MessageBox.Show("You need to read in a file first.");
}
}
}
我觉得必须有更好的方法来做到这一点。
到目前为止,非常感谢你的帮助!我确信这个问题没有得到解决的唯一原因是我缺乏沟通技巧。
答案 0 :(得分:1)
编辑根据您的上一次修改:
将每个字符串标识为相应的数量,然后在各自的组中找到总和
目前还不清楚你想要达到的目标。您应该已提供样本数据的所需结果。我假设金额是数字,组是名称组。
因此对Name
- 组来说,50+40+60=150
,DifferentName
= 50
和AnotherName
= 10
?
这将创建一个包含唯一名称及其相应金额的词典:
Dictionary<String, int> nameSums =
System.IO.File.ReadLines(path) // read lines from file
.Select(l => l.Split(',')) // split the line
.GroupBy(arr => arr[0]) // group by name
.ToDictionary(grp => grp.Key, grp => grp.Sum(arr => int.Parse(arr[1])));
如果你坚持采用数组方法,下面创建并初始化一个锯齿状数组(数组数组),其名称为第一个元素,总和为第二个:
String[][] nameSums = System.IO.File.ReadLines(path) // read lines from file
.Select(l => l.Split(',')) // split the line
.GroupBy(arr => arr[0]) // group by name
.Select(grp => new String[]{
grp.Key,
grp.Sum(arr => int.Parse(arr[1])).ToString()})
.ToArray();
第一次方法:
“使数字与其特定名称相对应”
所以我假设你想要属于每个数字的名字。如果这是真的,Dictionary<String, List<String>>
将是最佳选择:
var numNames = System.IO.File.ReadLines(path)
.Select(l => l.Split(','))
.GroupBy(arr => arr[1])
.ToDictionary(grp => grp.Key, grp => grp.Select(arr => arr[0]).ToList());
IEnumerable<String>
String[]
Dictionary
,(现在)唯一数字是键,名称的值为List<String>
如果您不熟悉dictionaries,通常可以通过密钥访问它们,因此如果您想知道号码"50"
的所有名称:
List<String> names = numNames["50"];
foreach(String name in names)
Console.Write("name={0}", name);
或者如果你想迭代所有:
foreach(var numName in numNames)
foreach(var name in numName.Value)
Console.Write("number={0} name={1}", numName.Key, name);
答案 1 :(得分:0)
myArray = File.ReadAllLines(myFileName).Select(l => l.Split(',')).ToArray();
请注意,这将是一个交错的数组,而不是二维数组。要创建二维的,可以使用
lines = File.ReadAllLines(myFileName).Select(l => l.Split(',')).ToArray();
myArray = new string[lines.Count(), 2];
for(int i = 0; i < lines.Length; i++)
{
myArray[i, 0] = lines[i, 0];
myArray[i, 1] = lines[i, 1];
}
答案 2 :(得分:0)
为什么不使用字典?
所以,
Dictionary<string,int> namesAndAges = new Dictionary<string,int>();
String[] line = new String[2];
while(there's still xml to read)
{
aLineOfXml = blah; //read a line of xml however you were gonna do it
line = aLineOfXml.Split(',');
namesAndAges.Add(line[0],line[1]);
}
while循环中的前两行会更好地压缩成一行,但为了清楚起见并且因为我不想添加任何xml解析代码,我将它拆分为。
答案 3 :(得分:0)
您的任务是IO绑定的。很可能你不会在改变代码方面获得任何好处。首先,您应该使用分析器来查找应用程序的瓶颈。
如果你有.Net 4,4.5或Silverlight使用ReadLines方法。它返回一个代表一组行的迭代器。片段:
List<KeyValuePair<string, double> values = new List<KeyValuePair<string, double>();
var lines = File.ReadLines(myFile);
foreach (var line in lines)
{
var data = line.Split(',');
var x = data[0];
var y = Double.Parse(data[1], CultureInfo.InvariantCulture);
var pair = new KeyValuePair<string, double>(x, y);
values .Add(pair);
}