2012-07-23 2 views
-1

2로 인덱싱 된 행뿐만 아니라 모든 행에 대해이 루프를 반복해야합니다. 또한 이중 구문 분석에서 오류가 발생합니다.C#을 사용하여 알 수없는 행에 대한 루핑

다음을 수행하는 효율적인 방법이 있습니까?

파일의 행 길이는 가변적 일 수 있습니다. 따라서 배열을 유지하여 각 행의 크기를 저장해야합니다.

public static void ReadFile() 
    { 
     int lineNo; 
     List<List<double>> numbers = new List<List<double>>(); 
     foreach (string line in File.ReadAllLines("Data.txt")) 
     { 
      var list = new List<float>(); 
      foreach (string s in line.Split(new[]{',', ' '}, StringSplitOptions.RemoveEmptyEntries)) 
      { 
       int i; 
       if(double.TryParse(s, out i)) 
       { 
        list.Add(i); 
        lineNo++; 
       } 
      } 
      numbers.Add(list); 
     } 

     var specialNumber = numbers[3][4];  // gives line 3 number 4 
     var specialLine = numbers[2].ToArray(); // gives an array of numbers of line 2 

     double[] rowTotal; 
     double[] squareRowTotal; 
     double[] rowMean; 

     //I need to loop this loop for all rows and not just the row indexed by 2. Also I am getting an error in the double parsing. 

     for (int j=0; j<(specialLine.Length); j++) 
     { 
      rowTotal[2] = rowTotal[2] + numbers[2][j]; 
      squareRowTotal[2] = squareRowTotal[2] + numbers[2][j] * numbers[2][j]; 
     } 

     for (int k = 0; k < lineNo; k++) 
     { 
      rowMean[k] = rowTotal[k]/numbers[k].Length; 
     } 
    } 

답변

0
public static void ReadFile() 
    { 
     List<List<double>> numbers = new List<List<double>>(); 
     foreach (string line in File.ReadAllLines(@"c:\temp\test.csv")) 
     { 
      var list = new List<double>(); 
      foreach (string s in line.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)) 
      { 
       double i; 
       if (Double.TryParse(s, out i)) 
       { 
        list.Add(i); 
       } 
      } 
      numbers.Add(list); 
     } 

     double[] rowTotal = new double[numbers.Count]; 
     double[] squareRowTotal = new double[numbers.Count]; 
     double[] rowMean = new double[numbers.Count]; 

     for(int row = 0; row < numbers.Count; row++) 
     { 
      var values = numbers[row].ToArray(); 

      rowTotal[row] = values.Sum(); 
      squareRowTotal[row] = values.Select(v => v * v).Sum(); 
      rowMean[row] = rowTotal[row]/rowTotal.Count(); 
     } 
    } 
1

둘째, 데이터 액세스 논리와 데이터 처리 논리를 분리하는 것이 좋습니다. 이름을 가지며 이중 값의 본질을 설명하는 일부 유형을 선언하는 것도 고려하십시오. 예 :

public class BowlingGame 
{ 
    private List<double> _scores = new List<double>(); 

    public BowlingGame(IEnumerable<double> scores) 
    { 
     _scores.AddRange(scores); 
    } 

    public double Total 
    { 
     get { return _scores.Sum(); } 
    } 

    // implementation for SquareTotal and Mean 
} 

그리고 분석 방법에서이 개체의 반환 목록 :

public static IEnumerable<BowlingGame> ParseFile() 
{ 
    List<BowlingGame> games = new List<BowlingGame>(); 
    foreach (string line in File.ReadAllLines(@"c:\temp\test.csv")) 
     games.Add(ParseGame(line)); 
    return games; 
} 

private static BowlingGame ParseGame(string line) 
{ 
    var scores = new List<double>(); 
    foreach (string s in line.Split(new[] { ',', ' ' })) 
    { 
     double score; 
     if (Double.TryParse(s, out score))    
      scores.Add(score); 
    } 

    return new BowlingGame(scores); 
} 

사용법 :

foreach(var game in GameParser.ParseFile()) 
{ 
    Console.WriteLine(game.Total); 
    Console.WriteLine(game.Mean); 
} 

무엇이 잘못된 코드와? 당신은

List<List<double>> numbers = new List<List<double>>(); 

을 선언하지만,이
var list = new List<int>(); 

는 또한 double.TryParse(s, out i) 예상하는 매개 변수를 두 배로 integeres의 목록을 추가하려고하지만 정수를 전달하는있다.

당신은 Linq에를 사용하여, 루프에서 값을 계산할 수 있습니다 (사용 그것을하기 전에 배열을 초기화하는 것을 잊지 마세요) :

double[] rowTotal = new double[numbers.Count]; 

for (int rowIndex = 0; rowIndex < numbers.Count; rowIndex++)    
    rowTotal[rowIndex] = numbers[rowIndex].Sum(); 

}

0

나는 당신의 대답은 다음과 같이해야한다고 생각 (루프 대신 LINQ를 사용했습니다!) :

public void ReadFile() 
{ 
    int lineNo = 0; 
    List<List<double>> numbers = new List<List<double>>(); 
    foreach (string line in File.ReadAllLines("Data.txt")) 
    { 
     var list = new List<double>(); 
     foreach (string s in line.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)) 
     { 
      double i; 
      if (double.TryParse(s, out i)) 
      { 
       list.Add(i); 
       lineNo++; 
      } 
     } 
     numbers.Add(list); 
    } 

    var rowsTotal = new List<double>(numbers.Count); 
    var squareRowTotal = new List<double>(numbers.Count); 
    var rowMean = new List<double>(numbers.Count); 

    rowsTotal.AddRange(numbers.Select(row => row.Sum())); 
    squareRowTotal.AddRange(numbers.Select(row => row.Sum(d => d*d))); 


    for (int k = 0; k < lineNo; k++) 
    { 
     rowMean[k] = rowsTotal[k]/numbers[k].Count; 
    } 
}