Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Monday, April 29, 2013 10:09 AM
A newbie in Linq. How do I check if an array of strings is contained FULLY in another bigger array using Linq. I tried: var result = Arr1.Intersect(Arr2,.....) way but this checks only for distinct elements.
Example:
string[] Arr1= new string[] { "A","a", "b", "y" };
string[] Arr2= new string[] {"s", "a", "z", "b", "c", "a"};
This should return {"a", "a", "b"} but not {"a", "b"}. Case-insensitive.
All replies (17)
Monday, April 29, 2013 8:10 PM ✅Answered
Hi,
you could intersect both and check the length of the returned collection:
int[] arr = { 1, 2, 3, 4, 5, 6 };
int[] arr1 = { 1, 5 };
var result = arr1.Intersect(arr);
if (result.Count() == arr1.Length)
MessageBox.Show("arr contins arr1 completely");
Regards,
Thorsten
Tuesday, April 30, 2013 8:04 PM ✅Answered
Just realized that I misunderstood your question. I thought you'ld like to check if one array contains all elements of another.
To check which elements build the intersection of both:
string[] arr = { "A", "a", "b", "y" };
string[] arr1 = { "s", "a", "z", "b", "c", "a" };
var elem = arr.Select(x => x.ToLower()).Select(x => (arr1.Contains(x.ToLower())) ? x : null);
foreach (var item in elem) {
Console.WriteLine(item);
}
Thursday, May 2, 2013 11:39 AM ✅Answered
string[] Arr1 = new string[] { "A", "a", "b", "y" };
string[] Arr2 = new string[] { "s", "a", "z", "b", "c", "a" };
var c = Arr2.Where(x => Arr1.Contains(x.ToLower()));
foreach (var i in c)
{
Console.Write(i);
}
This will print a,b,a
Hope fully this may help. Plz make it as answer if it is useful
Monday, April 29, 2013 10:38 AM
Try:
int[] arr = { 1, 2, 3, 4, 5, 6 };
int[] arr1 = { 1, 5 };
var elem = arr1.All(x => arr.Contains(x));Console.WriteLine("Array 1 contains all elements of Array 2: {0}", elem);
wizend
Monday, April 29, 2013 11:21 AM
I am not sure that this is possible with linq at all...
But it is very simple with sequential access to this objects, or we can call it old fashioned way with loops. Something like this if it helps:
string[] Arr1 = new string[] { "a", "a", "b", "y" };
string[] Arr2 = new string[] { "s", "a", "z", "b", "c", "a" };
List<string> arr2Copy = new List<string>(Arr2);
List<string> results = new List<string>();
foreach (string a in Arr1)
{
if (arr2Copy.Contains(a))
{
results.Add(a);
arr2Copy.RemoveAt(arr2Copy.IndexOf(a));
}
}
StringBuilder sb = new StringBuilder();
foreach (string s in results)
sb.Append(s + ", ");
MessageBox.Show(sb.ToString().TrimEnd(new char[] {',', ' '}));
if (helpful) then Vote();
Monday, April 29, 2013 8:35 PM
Does this help ?
string[] Arr1= new string[] { "A","a", "b", "y" };
string[] Arr2= new string[] {"s", "a", "z", "b", "c", "a"};
var result = from item in Arr2
where Arr1.Any(x => item.Contains(x))
select item;
result = result.OrderBy(x => x);
foreach (var x in result) { Console.WriteLine(x); }
Tuesday, April 30, 2013 5:32 PM
Thanks for the reply. However if suppose in Arr1, we remove the first element: "A", then the output is {"a", "a", "b"} which is incorrect. The required output should be {"a", "b"}.
Tuesday, April 30, 2013 5:39 PM
Thanks but the output does not work for repeated elements. For example if
int[] arr = { 1, 1, 3, 4, 5, 6 };int[] arr1 = { 1, 5, 1 };then the output should be { 1, 5, 1 }
Tuesday, April 30, 2013 6:11 PM
http://msdn.microsoft.com/en-us/library/bb460136.aspx
JP Cowboy Coders Unite!
Tuesday, April 30, 2013 8:09 PM
What you want is almost exactly the LINQ `Except` operation, except that the LINQ version only returns distinct items, rather than including duplicates. That's an easy enough modification though; we just use `Contains` instead of `Add` in the if check:
public static IEnumerable<T> MyExcept<T>(this IEnumerable<T> first, IEnumerable<T> second
,IEqualityComparer<T> comparer = null)
{
comparer = comparer ?? EqualityComparer<T>.Default;
HashSet<T> items = new HashSet<T>(second);
foreach (var item in first)
{
if (!items.Contains(item))
yield return item;
}
}
Now we can just call this method, passing in the appropriate comparer, and voila:
var result = Arr2.MyExcept(Arr1, StringComparer.InvariantCultureIgnoreCase)
.ToArray();
Tuesday, April 30, 2013 8:18 PM
Isn't there list.subset(),list.intersection() kind of methods available? There must be something like that. Try set class instead of list.
Faisal Ahmed Farooqui
Tuesday, April 30, 2013 8:18 PM
Hi,
int[] arr = { 1, 1, 3, 4, 5, 6 };
int[] arr1 = { 1, 5, 1};
var sums = arr.GroupBy(a => a).Select(b => b.Key * b.Count());
var sums2 = arr1.GroupBy(a => a).Select(b => b.Key * b.Count());
var result = sums.Intersect(sums2);
if (result.Count() == sums2.Count())
MessageBox.Show("arr contins arr1 completely");
Regards,
Thorsten
Tuesday, April 30, 2013 9:06 PM
Hi,
I jusr saw, you want to have the results from string-arrays...
string[] Arr1 = new string[] { "A", "a", "b", "y", };
string[] Arr2 = new string[] { "s", "a", "z", "b", "c", "a" };
var tmp = Arr1.GroupBy(a => a.ToLower());
var sums = tmp.Select(b => b.Key.ToCharArray()[0] * b.Count());
var tmp2 = Arr2.GroupBy(a => a.ToLower());
var sums2 = tmp2.Select(b => b.Key.ToCharArray()[0] * b.Count());
var result = sums2.Intersect(sums).Select(a => tmp.Where(b => b.Key == ((char)(a / b.Count())).ToString()).First().Key );
Regards,
Thorsten
Wednesday, May 1, 2013 9:28 PM
Example:
string[] Arr1= new string[] { "A","a", "b", "y" };
string[] Arr2= new string[] {"s", "a", "z", "b", "c", "a"};
This should return {"a", "a", "b"} but not {"a", "b"}. Case-insensitive.
namespace Abc
{
class Program : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return x.ToLower() == y.ToLower();
}
public int GetHashCode(string s)
{
return s == null ? 0 : s.Length;
}
static void Main(string[] args)
{
string[] a1 = { "Abcd", "b", "y", "ARGO", "War", "abcd", };
string[] a2 = { "B", "argo", "Q", "Asdf", "Abcd", "Z", "war", "b", "Cota", "E", };
IEnumerable<string> e = a1.Where(x => a2.Contains(x, new Program()));
}
}
}
foreach (string s in e)
Console.WriteLine(s);
•
Thursday, May 2, 2013 1:38 AM
Hi,
I re-read your question and came to a result very close to Wizend's:
string[] Arr1 = new string[] { "A", "a", "b", "y" };
string[] Arr2 = new string[] { "s", "a", "z", "b", "c", "a" };
var result = Arr1.Select(a => Arr2.Select(b => b.ToLower()).Contains(a.ToLower()) ? a : null).Where(b => b != null);
So if this fits your needs mark his reply as answer please.
Regards,
Thorsten
Thursday, May 2, 2013 4:18 AM
Hi,
yes you're right, I forgot to convert the Arr2-elements. I updated my above post. Thanks for informing me.
But there's still one question left. What output does the OP want for Arrays like:
string[] Arr1 = new string[] { "A", "a", "b", "y", "a" };
string[] Arr2 = new string[] { "s", "a", "z", "b", "c", "Y" };
? Shall all the "a"s from Arr1 be in the output? Or just one?
Regards,
Thorsten
Thursday, May 2, 2013 6:36 AM
Yes, but look at my arrays. There are 3 "a"s in the first and just one in the second. [The OPs has two "a"s in both arays] So how to process when there are more entities of a string in the first array than in the second?
Regards,
Thorsten