2016-03-08 35 views
0

我已經寫了一個函數,它給了我一個匹配多維正則表達式字符串的多維數組。 (FileCheck [] [])LINQ查詢找到多數重複的多維數組字符串

  1. FileCheck [0] //這串[]包含所有的文件名
  2. FileCheck [1] //這串[]是依賴於正則表達式匹配是0或1找到。
  3. FileCheck [2] //此字符串[]包含找到的第一個正則表達式的索引。

    foreach (string File in InputFolder) 
        { 
         int j = 0; 
         FileCheck[0][k] = Path.GetFileName(File); 
         Console.WriteLine(FileCheck[0][k]); 
         foreach (Regex Filemask in Filemasks) 
         { 
          if (string.IsNullOrEmpty(FileCheck[1][k]) || FileCheck[1][k] == "0") 
          { 
           if (Filemask.IsMatch(FileCheck[0][k])) 
           { 
            FileCheck[1][k] = "1"; 
            FileCheck[2][k] = j.ToString(); // This is the Index of the Regex thats Valid 
           } 
           else 
           { 
            FileCheck[1][k] = "0"; 
           } 
           j++; 
          } 
          Console.WriteLine(FileCheck[1][k]); 
         } 
         k++; 
        } 
        Console.ReadLine(); 
    
        // I need the Index of the Regex with the most valid hits 
    

我試圖寫一個函數,讓我擁有最重複的RegexIndex串。 這是我試過,但沒有工作:((我只得到字符串的計數最複製而不是字符串本身)

 // I need the Index of the Regex with the most valid hits 
     var LINQ = Enumerable.Range(0, FileCheck[0].GetLength(0)) 
      .Where(x => FileCheck[1][x] == "1") 
      .GroupBy(x => FileCheck[2][x]) 
      .OrderByDescending(x => x.Count()) 
      .First().ToList(); 
     Console.WriteLine(LINQ[1]); 

示例數據

 string[][] FileCheck = new string[3][]; 
     FileCheck[0] = new string[]{ "1.csv", "TestValid1.txt", "TestValid2.txt", "2.xml", "TestAlsoValid.xml", "TestValid3.txt"}; 
     FileCheck[1] = new string[]{ "0","1","1","0","1","1"}; 
     FileCheck[2] = new string[]{ null, "3", "3", null,"1","2"}; 

在這個例子中我需要爲LINQ查詢的結果是:

string result = "3"; 
+2

什麼意思是「但沒用」?你得到的結果是什麼?例外?任何不同的結果?請對你的問題更具體。 – HimBromBeere

+0

我得到大多數元素的計數,但不是RegexIndex的字符串。我編輯了我的問題,使其更清楚。 – kami

+0

@kami嗯,你確定?你上面的查詢給出了'2',這是字符串,而不是count(它是3) –

回答

1

用你現在的代碼,用'Key'代替'ToList()'就可以了。

var LINQ = Enumerable.Range(0, FileCheck[0].GetLength(0)) 
      .Where(x => FileCheck[1][x] == "1") 
      .GroupBy(x => FileCheck[2][x]) 
      .OrderByDescending(x => x.Count()) 
      .First().Key; 

由於未找到值的索引爲空,所以您也可以過濾掉空值並跳過查看FileCheck [1]數組。例如:

var maxOccurringIndex = FileCheck[2].Where(ind => ind != null) 
     .GroupBy(ind=>ind) 
     .OrderByDescending(x => x.Count()) 
     .First().Key; 

然而,只是一個建議,可以使用的類,而不是一個嵌套陣列,例如:

class FileCheckInfo 
{ 
    public string File{get;set;} 
    public bool Match => Index.HasValue; 
    public int? Index{get;set;} 

    public override string ToString() => $"{File} [{(Match ? Index.ToString() : "no match")}]"; 
} 

假設InputFolder是串的枚舉和Filemasks可枚舉「正則表達式」的,陣列可以填充有:

FileCheckInfo[] FileCheck = InputFolder.Select(f=> 
    new FileCheckInfo{ 
     File = f, 
     Index = Filemasks.Select((rx,ind) => new {ind, IsMatch = rx.IsMatch(f)}).FirstOrDefault(r=>r.IsMatch)?.ind 
     }).ToArray(); 

獲取最大發生將是幾乎相同的:

var maxOccurringIndex = FileCheck.Where(f=>f.Match).GroupBy(f=>f.Index).OrderByDescending(gr=>gr.Count()).First().Key; 

編輯 PS,以上都假設您需要重用結果,如果您只需使用Martin提供的方法就可以找到最好的結果! 如果目標只是爲了獲得最大值,您可以使用:

var maxOccurringIndex = Filemasks.Select((rx,ind) => new {ind, Count = InputFolder.Count(f=>rx.IsMatch(f))}) 
     .OrderByDescending(m=>m.Count).FirstOrDefault()?.ind; 
1

你的問題和代碼似乎很令人費解,我猜你有文件名列表和文件掩碼的另一份名單(常規。表達式),並且您想要查找與大多數文件名匹配的文件掩碼。這裏是一個辦法做到這一點:

var fileNames = new[] { "1.csv", "TestValid1.txt", "TestValid2.txt", "2.xml", "TestAlsoValid.xml", "TestValid3.txt" }; 
var fileMasks = new[] { @"\.txt$", @"\.xml$", "valid" }; 
var fileMaskWithMostMatches = fileMasks 
    .Select(
    fileMask => new { 
     FileMask = fileMask, 
     FileNamesMatched = fileNames.Count(
     fileName => Regex.Match(
      fileName, 
      fileMask, 
      RegexOptions.IgnoreCase | RegexOptions.CultureInvariant 
     ) 
      .Success 
    ) 
    } 
) 
    .OrderByDescending(x => x.FileNamesMatched) 
    .First() 
    .FileMask; 

與樣本數據的fileMaskWithMostMatchesvalid

注意,Regex類會做正則表達式的一些緩存,但是如果你有很多的正則表達式會更effecient創建隱含fileNames.Count外的正則表達式for-each循環,以避免再次重現相同的正則表達式再次(根據複雜性,創建正則表達式可能會花費不少的時間)。

1

作爲Martin答案的替代方法,下面是現有Linq查詢的一個簡單版本,它提供了期望的結果;

var LINQ = FileCheck[2] 
       .ToLookup(x => x)     // Makes a lookup table 
       .OrderByDescending(x => x.Count()) // Sorts by count, descending 
       .Select(x => x.Key)     // Extract the key 
       .FirstOrDefault(x => x != null); // Return the first non null key 
                // or null if none found. 
0

這不是更簡單嗎?

string result = FileCheck[2] 
    .Where(x => x != null) 
    .GroupBy(x => x) 
    .OrderByDescending(x => x.Count()) 
    .FirstOrDefault().Key;