2012-07-22 16 views
2

Tout comme dans le titre. J'ai un tableau de chaînes et un deuxième tableau de chaînes. Je veux afficher le résultat dans ce type de motif: premier élément du premier tableau - puis tous les éléments du deuxième tableau qui se produit dans le premier élément du premier tableau. Après ce deuxième élément du premier tableau et tous les éléments du deuxième tableau qui se produit dans le deuxième élément du premier tableau. Etc. Par exemple:C# - recherche un tableau de chaînes utilisant des chaînes d'un autre tableau de chaînes

string[] arrayA = {"Lorem ipsum dolor sit amet, justo", "notgin like good cold beer"}; 
string[] arrayB = {"justo","beer","lorem"} 
for (int i = 0; i < arrayA.Length; i++) 
    { 
     Console.WriteLine(arrayA[i]); 

     for (int j = 0; j < arrayB.Length; j++) 
     { 
      int controlIndex = arrayA[i].IndexOf(arrayB[j]); 
      if (controlIndex != -1) 
      { 
       Console.Write(" :--contains-->" + arrayB[j]); 
      } 

    } 

}

Ainsi, le résultat devrait ressembler à ceci:

  • Lorem ipsum dolor sit amet, justo: - contient ->justo, lorem
  • notgin comme bonne bière froide: - contient ->bière.

Mais le mien résultat est: - Lorem ipsum dolor sit amet, justo: - contient ->justo - notgin comme une bonne bière froide: - contient ->bière.

Comme vous pouvez le voir il n'y a pas lorem liste

Répondre

2

Ce n'est pas difficile du tout si vous cassez votre problème. Tout d'abord, évitez de traiter avec des tableaux et des index en eux. Il suffit d'utiliser IEnumerable<T>, il va rendre votre vie plus facile.

Voilà comment je vois:

D'abord, vous voulez trouver toutes les chaînes d'un tableau needles, qui font partie d'une chaîne, haystack.

public static IEnumerable<string> MatchingStrings(string haystack, IEnumerable<string> needles) 
{ 
    return needles.Where(needle => haystack.Contains(needle)); 
} 

Cela renverra un IEnumerable de toutes les chaînes de needles qui font partie de haystack. Puis, vous voulez simplement parcourir toutes vos chaînes de recherche, j'appellerai ça haystacks.

static void Main(string[] args) 
    { 
     var haystacks = new[] { 
      "Lorem ipsum dolor sit amet, justo", 
      "notgin like good cold beer" 
     }; 

     var needles = new[] {"justo", "beer", "lorem"}; 

     foreach (var haystack in haystacks) { 
      Console.Write(haystack + " contains --> "); 
      var matches = MatchingStrings(haystack, needles); 

      Console.WriteLine(String.Join(",", matches)); 
     } 

     Console.ReadLine(); 
    } 

Notez que String.Contains() est sensible à la casse. Donc "Lorem" ne correspondra pas "lorem". Si vous voulez ce comportement, vous devrez d'abord les convertir en minuscules.

public static IEnumerable<string> MatchingStringsCaseInsensitive(string haystack, IEnumerable<string> needles) 
{ 
    var h = haystack.ToLower(); 
    return needles.Where(needle => h.Contains(needle.ToLower())); 
} 
+0

C'est bon mais ça va aussi retourner quelque chose comme ça LoremTy ce qui n'est pas bon. Ne devrait revenir que lorsqu'il y a un "Lorem". – born2fr4g

+0

Vous n'avez jamais spécifié que c'était par des mots. On devrait pouvoir modifier ceci cependant, en utilisant 'String.Split' pour diviser chaque meule de foin par des espaces, en mots, et en les recherchant. –

+0

Merci encore pour cet exemple. Il y a beaucoup à apprendre;). – born2fr4g

1
string[] arrayA = {"Lorem ipsum dolor sit amet, justo", "notgin like good cold beer"}; 
string[] arrayB = {"justo","beer","lorem"}; 

foreach (var s in arrayA) 
{ 
    Console.Write(s + " contains: " + 
        string.Join(",", arrayB.Where(s.Contains))); 
} 

Et si vous voulez ignorer la casse:

foreach (var s in arrayA) 
{ 
    Console.Write(s + " contains: " + 
        string.Join(",", arrayB.Where(x => 
         s.IndexOf(x, StringComparison.OrdinalIgnoreCase) != -1))); 
} 
+0

de Nice :). J'ai vraiment besoin d'utiliser des expressions lambda. Mais après avoir pensé que mon code était bon (j'ai fait une erreur avec la capitale Lorem alors c'est pourquoi il n'a pas été répertorié). Merci quand même. – born2fr4g

1
foreach(var a in arrayA) 
{ 
    Console.WriteLine("a: " + a); 
    Console.WriteLine("bs: " + 
     String.Join(", ", arrayB.Where(b => a.IndexOf(b) > -1))); 
} 

Aussi, si vous voulez dire de ne pas se soucier de cas , a.IndexOf(b) serait a.IndexOf(b, StringComparison.OrdinalIgnoreCase).

+0

Pas besoin de '.ToArray()' dans .net 4;) – SimpleVar

+0

@YoryeNathan merci, trop habitué à 3.5. Je souhaite qu'ils ajouteraient cette même surcharge au constructeur de la chaîne. –

+0

Que voulez-vous dire, comme 'new string (myIEnumerable)'? Quelle serait l'idée? – SimpleVar

1

Ceci est la solution Linq:

var result = arrayA.Select(a => new{ 
    A = a, 
    bContains = arrayB.Where(b => a.IndexOf(b, 0, StringComparison.CurrentCultureIgnoreCase) > -1)    
}); 

foreach(var x in result) 
{ 
    Console.WriteLine("{0}:--contains-->{1}", x.A, string.Join(",", x.bContains)); 
} 

Voici une démo: http://ideone.com/wxl6I

+0

Pourquoi utiliser des types anonymes quand vous n'en avez pas vraiment besoin? – SimpleVar

+0

@YoryeNathan: Parce que je ne connais pas le résultat souhaité, il peut s'agir d'un 'Console.WriteLine', il peut s'agir d'un tableau, d'une liste, d'une classe ou d'un tuple. J'ai donc créé la chose la plus dynamique, afin que OP puisse l'utiliser pour créer ce qu'il veut. –

+0

Mais vous connaissez le résultat souhaité - il veut les imprimer. Il le veut même d'une manière très spécifique. On dirait qu'il n'y en a pas beaucoup plus. – SimpleVar

1

Voici ma tentative

string[] arrayA = {"lorem ipsum dolor sit amet, justo", "notgin like good cold beer"}; 
string[] arrayB = {"justo", "beer", "lorem"}; 

foreach (var item in from a in arrayA from b in arrayB where a.Contains(b) select new {a, b}) 
{ 
    Console.WriteLine(item.a); 
    Console.WriteLine(item.b); 
} 

Note: Contains est un cas comparer et vous sensible » Il va falloir écrire un comparateur personnalisé (comme d'autres réponses l'ont déjà fait)

0

Lorem est en majuscule. Essayez d'utiliser une recherche insensible à la casse: .indexOf(string, StringComparison.CurrentCultureIgnoreCase)

0

Je vous ai donné toutes les réponses possibles, mais la méthode contains va créer un problème qui retournera vrai dans le cas mentionné ci-dessous.

reference_string = "Hello Stack Overflow" 
test_string = "Over" 

alors essayez d'éviter contient parce que contient la méthode sera

« Retourne une valeur indiquant si l'objet System.String spécifié se produit au sein de la cette chaîne »

Note: la StringComparer.OrdinalIgnoreCase est ajouté pour insensible à la casse.

/// <summary> 
     /// Compares using binary search 
     /// </summary> 
     /// <param name="input"> search input</param> 
     /// <param name="reference"> reference string</param> 
     /// <returns> returns true or false</returns> 
     public bool FatMan(string input, string reference) 
     { 
      string[] temp = reference.Split(); 
      Array.Sort(temp); 
      List<string> refe = new List<string> { }; 
      refe.AddRange(temp); 

      string[] subip = input.Split(); 
      foreach (string str in subip) 
      { 
       if (refe.BinarySearch(str, StringComparer.OrdinalIgnoreCase) < 0) 
       { 
        return false; 
       } 
      } 

      return true; 
     } 

     /// <summary> 
     /// compares using contains method 
     /// </summary> 
     /// <param name="input"> search input</param> 
     /// <param name="reference"> reference string</param> 
     /// <returns> returns true or false</returns> 
     public bool Hiroshima(string input, string reference) 
     { 
      string[] temp = reference.Split(); 
      Array.Sort(temp); 
      List<string> refe = new List<string> { }; 
      refe.AddRange(temp); 
      string[] subip = input.Split(); 

      foreach (string str in subip) 
      { 
       if (!refe.Contains(str, StringComparer.OrdinalIgnoreCase)) 
       { 
        return false; 
       } 
      } 

      return true; 
     } 


     public bool Nakashaki(string input, string reference) 
     { 
      string[] temp = reference.Split(); 
      Array.Sort(temp); 
      List<string> refe = new List<string> { }; 
      refe.AddRange(temp); 
      string[] subip = input.Split(); 

      int result = (from st in subip where temp.Contains(st, StringComparer.OrdinalIgnoreCase) select st).Count(); 

      if (result <= 0) 
      { 
       return false; 
      } 

      return true; 
     } 

     /// <summary> 
     /// compares using contains method 
     /// </summary> 
     /// <param name="input"> search input</param> 
     /// <param name="reference"> reference string</param> 
     /// <returns> returns true or false</returns> 
     public bool LittleBoy(string input, string reference) 
     { 
      string[] subip = input.Split(); 
      foreach (string str in subip) 
      { 
       if (!reference.Contains(str)) 
       { 
        return false; 
       } 
      } 

      return true; 
     } 
-1
bool oupt ; 
string[] strarray1 = new string[3]{"abc","def","ghi" }; 
string[] strarray2 = new string[4] { "648", "888", "999", "654" }; 
if (strarray1.All(strarray.Contains)) 
    oupt = true; 
else 
    oupt = false; 
+1

Salut et bienvenue à SO! S'il vous plaît ajouter quelques lignes le long de votre code pour expliquer pourquoi vous pensez que votre réponse est une bonne solution à la question initiale, merci. – m4rtin

Questions connexes