【问题标题】:c# - search a string array using strings from another string arrayc# - 使用来自另一个字符串数组的字符串搜索一个字符串数组
【发布时间】:2012-07-20 18:17:46
【问题描述】:

就像标题一样。我得到了一个字符串数组和第二个字符串数组。我想以这种模式显示结果:第一个数组的第一个元素 - 然后是第二个数组中出现在第一个数组的第一个元素中的所有元素。在第一个数组的第二个元素和第二个数组中出现在第一个数组的第二个元素中的所有元素之后。等等。 例如:

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]);
          }

    }

}

所以结果应该是这样的:

  • Lo​​rem ipsum dolor sit amet, justo :--contains--> justo,lorem
  • notgin like good cold beer :--contains--> beer.

但我的结果是: - Lorem ipsum dolor sit amet, justo :--包含--> justo - notgin like good cold beer :--contains--> beer.

如您所见,没有列出 lorem

【问题讨论】:

    标签: c# arrays string search


    【解决方案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;
    

    【讨论】:

    • 您好,欢迎来到 SO!请在您的代码中添加几行来解释为什么您认为您的答案是原始问题的一个很好的解决方案,谢谢。
    【解决方案2】:

    我已经给了你所有可能的答案,但是 contains 方法会产生一个问题,在下面提到的情况下它也会返回 true。

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

    所以尽量避免包含,因为 contains 方法会

    "返回一个值,指示指定的 System.String 对象是否出现在 this 字符串中"

    注意:添加 StringComparer.OrdinalIgnoreCase 是为了不区分大小写。

    /// <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;
            }
    

    【讨论】:

      【解决方案3】:

      如果您将问题分解一些,这一点也不难。首先,远离处理数组和索引。只需使用IEnumerable&lt;T&gt;,它会让您的生活更轻松。

      我是这样看的:

      首先,您要从数组needles 中查找所有字符串,它们是字符串haystack 的一部分。

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

      这将返回 needles 中属于 haystack 的所有字符串的 IEnumerable。

      然后,您想简单地遍历所有搜索字符串,我将其称为 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();
          }
      

      请注意,String.Contains() 区分大小写。所以“Lorem”不会匹配“lorem”。如果您想要这种行为,您必须先将它们转换为小写。

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

      【讨论】:

      • 这很好,但也会返回类似 LoremTy 这样不好的东西。仅当存在“Lorem”时才应返回。
      • 您从未指定它是通过文字。然而,人们应该能够修改这一点,使用String.Split 将每个干草堆按空格分割成单词,然后搜索它们。
      • 总有!这就是为什么它很有趣。如果对您有帮助,请记住接受其中一个答案。
      【解决方案4】:

      Lorem 大写。尝试使用不区分大小写的搜索:.indexOf(string, StringComparison.CurrentCultureIgnoreCase)

      【讨论】:

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

        此外,如果您不关心大小写,a.IndexOf(b) 将是 a.IndexOf(b, StringComparison.OrdinalIgnoreCase)

        【讨论】:

        • .net 4 中不需要.ToArray() ;)
        • @YoryeNathan 谢谢,太习惯了 3.5。我希望他们将同样的重载添加到字符串构造函数中。
        • 你是什么意思,比如new string(myIEnumerable)?会有什么想法?
        • @YoryeNathan new string(IEnumerable&lt;char&gt;)。最简单的示例是反转字符串。如果存在该构造函数,您可以执行new string(myString.Reverse())
        • 为什么不在返回反向字符串的字符串上使用 Reverse 方法?
        【解决方案6】:

        这是我的尝试

        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);
        }
        

        注意:Contains 是区分大小写的比较器,您需要编写一个自定义比较器(正如其他答案已经完成的那样)

        【讨论】:

          【解决方案7】:

          这是 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));
          }
          

          这是一个演示:http://ideone.com/wxl6I

          【讨论】:

          • 为什么在不需要时使用匿名类型?
          • @YoryeNathan:因为我不知道想要的结果,它可能是Console.WriteLine,它可能是一个数组、列表、类或元组。所以我创造了最有活力的东西,这样 OP 就可以用它来创造他想要的东西。
          • 但是你知道想要的结果——他想打印出来。他甚至以一种非常具体的方式想要它。看起来没有更多内容了。
          • @YoryeNathan:我的解决方案正是这样做的,无需额外的工作。但这可能是为了说明要求而进行的简化。
          【解决方案8】:
          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)));
          }
          

          如果你想忽略大小写:

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

          【讨论】:

          • 很好:)。我真的需要使用 lambda 表达式。但是在认为我的代码很好之后(我在大写 Lorem 上犯了一个错误,所以这就是它没有被列出的原因)。无论如何谢谢你。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-28
          • 2011-08-15
          相关资源
          最近更新 更多