2

Just like in the title. I got one array of strings and second array of strings. I want to display result in this kind of pattern: first element of the first array - then all elements from second array that occurs in first element of first array. After that second element of first array and all elements from second array that occurs in second element of first array. And so on. For example:

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

    }

}

So the result should looks like this:

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

But mine result is: - Lorem ipsum dolor sit amet, justo :--contains--> justo - notgin like good cold beer :--contains--> beer.

So as you can see there is no lorem listed

0

8 Answers 8

2

This is not hard at all if you break your problem down some. First of all, get away from dealing with arrays and indexes into them. Just use IEnumerable<T>, it will make your life easier.

Here's how I see it:

First, you want to find all strings from an array needles, that are part of a string, haystack.

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

This will return an IEnumerable of all of the strings from needles that are a part of haystack.

Then, you want to simply iterate over all of your search strings, I'll call that 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();
    }

Note that String.Contains() is case-sensitive. So "Lorem" will not match "lorem". If you want this behavior, you will have to convert them to lowercase first.

public static IEnumerable<string> MatchingStringsCaseInsensitive(string haystack, IEnumerable<string> needles)
{
    var h = haystack.ToLower();
    return needles.Where(needle => h.Contains(needle.ToLower()));
}
Sign up to request clarification or add additional context in comments.

3 Comments

This is good but will also return something like this LoremTy which is not good. Should only return when there is a "Lorem".
You never specified that it was by words. One should be able to modify this however, using String.Split to split each haystack by spaces, into words, and searching those.
There always is! That's why it's fun. Remember to accept one of the answers if it helped you.
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)));
}

And if you want to ignore case:

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

1 Comment

Nice :). I really need to use lambda expressions. But after thinking my code was good (i made a mistake with capital Lorem so thats why it hasnt been listed). Thank you any way.
1

This is the Linq solution:

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

Here's a demo: http://ideone.com/wxl6I

4 Comments

Why use anonymous types when you don't really have to?
@YoryeNathan: Because i don't know the desired result, it might be a Console.WriteLine, it might be an array,list,class or tuple. So i've created the most dynamic thing, so that OP can use it to create what he want.
But you do know the desired result - he wants to print them. He even wants it in a very specific way. Looks like there isn't much more to it.
@YoryeNathan: And my solution does exactly that without extra work. But that might be a simplification to illustrate the requirement.
1

Here's my attempt

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 is a case sensitive compare and you'll need to write a custom comparer (as other answers have already done)

Comments

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

Also if you mean to not care about case, a.IndexOf(b) would be a.IndexOf(b, StringComparison.OrdinalIgnoreCase).

8 Comments

No need for .ToArray() in .net 4 ;)
@YoryeNathan thank you, too used to 3.5. I wish they'd add that same overload to the string constructor.
What do you mean, like new string(myIEnumerable)? What would be the idea?
@YoryeNathan new string(IEnumerable<char>). Simplest example is reversing a string. If that constructor existed you could do new string(myString.Reverse()).
Why not just having a Reverse method on string that returns a reversed string?
|
0

Lorem is capitalized. Try using a case-insensitive search: .indexOf(string, StringComparison.CurrentCultureIgnoreCase)

Comments

0

I have given you all the possible answers , but the contains method will create a problem that it will also return true in the case as below mentioned.

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

so try to avoid contains because contains method will

"Returns a value indicating whether the specified System.String object occurs within the this string"

Note: the StringComparer.OrdinalIgnoreCase is added for case insensitive.

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

Comments

-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 Comment

Hi and welcome to SO ! Please add a few lines along your code to explain why you think your answer is a good solution to the original question, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.