2017-08-09 45 views
1

我有2個列表,PlanetsFavorites。它們包含多個由空格分隔的單詞。拆分列表成子列表,List.Contains()找不到匹配

我將列表按空間拆分爲子列表。

現在我想檢查Planets是否包含Favorites的名稱。

Planets.Contains()找不到匹配項。

http://rextester.com/YLOG10363

// Planets List 
// 
List<string> Planets = new List<string>(); 
Planets.Add("First Mercury Gray"); 
Planets.Add("Second Venus Yellow"); 
Planets.Add("Third Earth Blue"); 
Planets.Add("Fourth Mars Red"); 

// Favorites List 
// 
List<string> Favorites = new List<string>(); 
Favorites.Add("Venus Hot"); 
Favorites.Add("Mars Cold"); 

// Sublists 
// 
string[] arrPlanets = null; 
string[] arrFavorites = null; 
List<string> Order = new List<string>(); 
List<string> Names = new List<string>(); 
List<string> Colors = new List<string>(); 



// In each Line of Planets & Favorites Lists, Split by Space 
// Add Word to it's Sublist 
// 
for (int i = 0; i < Planets.Count; i++) 
{ 
    // Create Planet Sublists 
    arrPlanets = Convert.ToString(Planets[i]).Split(' '); 
    Order.Add(arrPlanets[0]); 
    Names.Add(arrPlanets[1]); 
    Colors.Add(arrPlanets[2]); 

    // Create Favorites Sublist 
    // Prevent Favorites index from going out of range 
    if (i < Favorites.Count()) 
    { 
     arrFavorites = Convert.ToString(Favorites[i]).Split(' '); 

     // Display Message if Planets List Contains a Name from Favorites 
     // 
     if (Planets.Contains(arrFavorites[0])) 
     { 
      Console.WriteLine("Favorite Detected."); 
     } 
    } 
} 
+2

你爲什麼在字符串上使用Convert.ToString?另外,我建議您將這些值解析爲包含3個屬性的類,然後使用該類類型的列表。 – juharr

+0

'公共類Planet {公共字符串Order {set;得到; } public string Name {set;得到; } public string Color {set;得到; }}' –

+0

@juharr我有一個錯誤,說它不能將字符串轉換爲字符串。但是在重構之後,似乎無需這樣做就可以進行編譯。 –

回答

2

好了,我看了所有的答案,你可能想在這個可能性看爲好,因爲它代表重構你的代碼量最小:

更換

if (Planets.Contains(arrFavorites[0])) 

隨着

if (Planets.Any(p => p.Contains(arrFavorites[0]))) 

不是最高性能,因爲有更好的算法來檢查匹配項。但看着你的代碼,它看起來並不像你最重要的東西。那麼可能,那麼我的方法可能是有意義的。

希望有所幫助。

1

如果你想看看在任何喜歡的任何單詞包含在任何星球,那麼你只需要到收藏分成詞,然後看看是否有行星包含任何字。

因此,讓所有的收藏的話,我們可以做這樣的事情:

var favoriteWords = Favorites.SelectMany(i => i.Split(' ')); 

現在,我們可以遍歷所有的行星,看看是否有任何匹配:

Planets.ForEach(p => 
{ 
    if (favoriteWords.Any(p.Contains)) 
    { 
     Console.WriteLine($"One of your favorite planets is: {p}"); 
    } 
}); 

,其結果是:

enter image description here

或者,如果你只是萬特d,顯示相匹配的是,最喜歡的話,你可以這樣做:

Console.WriteLine("These favorite words were matched: "); 
Planets.ForEach(p => favoriteWords.Where(p.Contains).ToList().ForEach(Console.WriteLine)); 

enter image description here

1

不要使用數組,如果你不知道你想讓他們持有的項目數和DON '故意將變量設置爲null。 使用列表來代替:

List<string> planets = new List<string>(); 
List<string> favorites = new List<string>(); 

這就是說你的代碼是完全錯誤的。 你所想要實現這樣的:

List<string> Planets = new List<string>(); 
Planets.Add("First Mercury Gray"); 
Planets.Add("Second Venus Yellow"); 
Planets.Add("Third Earth Blue"); 
Planets.Add("Fourth Mars Red"); 

List<string> Favorites = new List<string>(); 
Favorites.Add("Venus Hot"); 
Favorites.Add("Mars Cold"); 

// Unless you need favorites to hold tokens seperated by a white space 
// you shouldn't make another list such as this one: 
List<string> faveKeywords = Favorites.SelectMany(fave => fave.Split(' ')).ToList(); 
foreach (var token in from line in Planets from token in line.Split(' ') where faveKeywords.Contains(token) select token) 
{ 
    Console.WriteLine($"Favorite detected: {token}"); 
} 

或者,如果你繼續堅持做該命令,顏色,名稱:

foreach (var tokens in Planets.Select(str => str.Split(' '))) 
{ 
    Order.Add(tokens[0]); 
    Names.Add(tokens[1]); 
    Colors.Add(tokens[2]); 
    foreach (var token in tokens.Where(token => faveKeywords.Contains(token))) 
    { 
     Console.WriteLine($"Favorite detected: {token}"); 
    } 
} 

你需要從實例來學習像這樣的並觀察比你問的更多。

+0

我唯一的問題是,List '性能較差那個簡單的數組。但是這種差異真的會在負載壓力下變得輕微。 **底線:沒有經驗法則**。只需要瞭解技術權衡是什麼。瞭解技術成本和收益是什麼,是關鍵,而不是奴隸般的遵守「經驗法則」。 – code4life

+0

我很抱歉,但是您關於不將數組設置爲null的聲明在此處無效。 OP給出的代碼清楚地表明瞭我的意圖,我認爲你並不理解。因此:不要依賴經驗法則。他們只會讓你陷入困境。最好的結果不是你在這裏想的。 – code4life

2

這真的不是很清楚你要完成什麼,但是既然你說你要找出是否Planets包含任何名義從Favorites,並假設名稱是始終在每個喜歡的第一個字,

var PlanetsHasFavorite = Planets.Any(p => Favorites.Select(f => f.Split(' ')[0]).Any(f => p.Split(' ').Contains(f))); 

PlanetsHasFavorite將是真實的,如果任何行星匹配名稱從Favorites

假設你的意思是你真正想要得到的匹配行星的名單,

var PlanetsAreFavorite = Planets.Where(p => Favorites.Select(f => f.Split(' ')[0]).Any(f => p.Split(' ').Contains(f))).ToList();