C# Windows Forms中如何对存储为字符串类型的数值列表计算平均值
Got it, let's work through this problem together. You've got three List<string>s holding numeric values from your file, and you need to calculate the average of each corresponding set of values for your skiTime variable. Here's how to do it smoothly while keeping your original string lists intact for the DataGridView:
Step 1: Adjust Your skiTime Declaration
Since each line in your file has a set of three times, you'll need a list to store all the averages (not a single string). Update your declaration to:
List<double> skiTime = new List<double>(); // Use double for decimal averages, or int if you only need whole numbers
Step 2: Calculate Averages Safely
You have two solid options here—calculate as you read each line, or process all lines after reading them. Both work well, let's cover both:
Option 1: Calculate Averages While Reading the File
This avoids storing all data first and looping again. Also, the using statement automatically closes your StreamReader, so you don't need the redundant sr.Close() call:
using (StreamReader sr = new StreamReader("pupilSkiTimes.txt")) { string line = ""; while ((line = sr.ReadLine()) != null) { string[] components = line.Split("~".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); skiTime1.Add(components[2]); skiTime2.Add(components[3]); skiTime3.Add(components[4]); // Convert strings to numbers and calculate average if (double.TryParse(components[2], out double time1) && double.TryParse(components[3], out double time2) && double.TryParse(components[4], out double time3)) { double average = (time1 + time2 + time3) / 3; skiTime.Add(average); } else { // Handle invalid data (e.g., non-numeric strings in the file) skiTime.Add(0); // Add a default value, or skip this entry entirely MessageBox.Show($"Warning: Invalid time values in line: {line}"); } } }
Option 2: Calculate Averages After Reading All Lines
If you prefer to process all data at once after reading, use this loop right after your using block:
// After reading all lines into skiTime1, skiTime2, skiTime3 for (int i = 0; i < skiTime1.Count; i++) { if (double.TryParse(skiTime1[i], out double time1) && double.TryParse(skiTime2[i], out double time2) && double.TryParse(skiTime3[i], out double time3)) { skiTime.Add((time1 + time2 + time3) / 3); } else { // Handle invalid entries here skiTime.Add(0); MessageBox.Show($"Invalid data at line {i + 1}"); } }
Key Notes
- Why
TryParse? It safely converts strings to numbers without crashing your program if a line has non-numeric values (like typos in the file). If you're 100% sure all values are valid integers, you can swap inint.TryParseinstead. - Keep Your String Lists Intact Your original
skiTime1,skiTime2,skiTime3stay asList<string>—perfect for binding to your DataGridView, no changes needed there. - Decimal vs Integer Averages Use
doubleif you need precise decimal averages (e.g., 10.333 instead of 10). If you only care about whole numbers, switch toint(just note that integer division will round down, e.g., (10+10+11)/3 = 10 instead of 10.333).
内容的提问来源于stack exchange,提问作者ShadySpiritomb

