Related
In Java, Arrays.equals() allows to easily compare the content of two basic arrays (overloads are available for all the basic types).
Is there such a thing in C#? Is there any "magic" way of comparing the content of two arrays in C#?
You could use Enumerable.SequenceEqual. This works for any IEnumerable<T>, not just arrays.
Use Enumerable.SequenceEqual in LINQ.
int[] arr1 = new int[] { 1,2,3};
int[] arr2 = new int[] { 3,2,1 };
Console.WriteLine(arr1.SequenceEqual(arr2)); // false
Console.WriteLine(arr1.Reverse().SequenceEqual(arr2)); // true
Also for arrays (and tuples) you can use new interfaces from .NET 4.0: IStructuralComparable and IStructuralEquatable. Using them you can not only check equality of arrays but also compare them.
static class StructuralExtensions
{
public static bool StructuralEquals<T>(this T a, T b)
where T : IStructuralEquatable
{
return a.Equals(b, StructuralComparisons.StructuralEqualityComparer);
}
public static int StructuralCompare<T>(this T a, T b)
where T : IStructuralComparable
{
return a.CompareTo(b, StructuralComparisons.StructuralComparer);
}
}
{
var a = new[] { 1, 2, 3 };
var b = new[] { 1, 2, 3 };
Console.WriteLine(a.Equals(b)); // False
Console.WriteLine(a.StructuralEquals(b)); // True
}
{
var a = new[] { 1, 3, 3 };
var b = new[] { 1, 2, 3 };
Console.WriteLine(a.StructuralCompare(b)); // 1
}
SequenceEqual will only return true if two conditions or met.
They contain the same elements.
The elements are in the same order.
If you only want to check if they contain the same elements regardless of their order and your problem is of the type
Does values2 contain all the values contained in values1?
you can use LINQ extension method Enumerable.Except and then check if the result has any value. Here's an example
int[] values1 = { 1, 2, 3, 4 };
int[] values2 = { 1, 2, 5 };
var result = values1.Except(values2);
if(result.Count()==0)
{
//They are the same
}
else
{
//They are different
}
And also by using this you get the different items as well automatically. Two birds with one stone.
Keep in mind, if you execute your code like this
var result = values2.Except(values1);
you will get different results.
In my case I have a local copy of an array and want to check if anything has been removed from the original array so I use this method.
For .NET 4.0 and higher you can compare elements in array or tuples via using StructuralComparisons type:
object[] a1 = { "string", 123, true };
object[] a2 = { "string", 123, true };
Console.WriteLine (a1 == a2); // False (because arrays is reference types)
Console.WriteLine (a1.Equals (a2)); // False (because arrays is reference types)
IStructuralEquatable se1 = a1;
//Next returns True
Console.WriteLine (se1.Equals (a2, StructuralComparisons.StructuralEqualityComparer));
If you would like to handle null inputs gracefully, and ignore the order of items, try the following solution:
static class Extensions
{
public static bool ItemsEqual<TSource>(this TSource[] array1, TSource[] array2)
{
if (array1 == null && array2 == null)
return true;
if (array1 == null || array2 == null)
return false;
if (array1.Count() != array2.Count())
return false;
return !array1.Except(array2).Any() && !array2.Except(array1).Any();
}
}
The test code looks like:
public static void Main()
{
int[] a1 = new int[] { 1, 2, 3 };
int[] a2 = new int[] { 3, 2, 1 };
int[] a3 = new int[] { 1, 3 };
Console.WriteLine(a1.ItemsEqual(a2)); // Output: True.
Console.WriteLine(a2.ItemsEqual(a3)); // Output: False.
Console.WriteLine(a3.ItemsEqual(a2)); // Output: False.
int[] a4 = new int[] { 1, 1 };
int[] a5 = new int[] { 1, 2 };
Console.WriteLine(a4.ItemsEqual(a5)); // Output: False
Console.WriteLine(a5.ItemsEqual(a4)); // Output: False
int[] a6 = null;
int[] a7 = null;
int[] a8 = new int[0];
Console.WriteLine(a6.ItemsEqual(a7)); // Output: True. No Exception.
Console.WriteLine(a8.ItemsEqual(a6)); // Output: False. No Exception.
Console.WriteLine(a7.ItemsEqual(a8)); // Output: False. No Exception.
}
For unit tests, you can use CollectionAssert.AreEqual instead of Assert.AreEqual.
It is probably the easiest way.
For some applications may be better:
string.Join(",", arr1) == string.Join(",", arr2)
Assuming array equality means both arrays have equal elements at equal indexes, there is the SequenceEqual answer and the IStructuralEquatable answer.
But both have drawbacks, performance wise.
SequenceEqual implementation in .Net Framework will not shortcut when the arrays have different lengths, and so it may enumerate one of them entirely, comparing each of its elements.
This said, depending on the .Net flavor (like .Net5), it may shortcut, see this comment. So for an up-to-date .Net project, SequenceEqual should be a good choice.
IStructuralEquatable is not generic and may cause boxing of each compared value. Moreover it is not very straightforward to use and already calls for coding some helper methods hiding it away.
It may be better, performance wise, to use something like:
bool ArrayEquals<T>(T[] first, T[] second)
{
if (first == second)
return true;
if (first == null || second == null)
return false;
if (first.Length != second.Length)
return false;
for (var i = 0; i < first.Length; i++)
{
if (!first[i].Equals(second[i]))
return false;
}
return true;
}
But of course, that is not either some "magic way" of checking array equality.
So currently, no, there is not really an equivalent to Java Arrays.equals() in .Net.
This LINQ solution works, not sure how it compares in performance to SequenceEquals. But it handles different array lengths and the .All will exit on the first item that is not equal without iterating through the whole array.
private static bool arraysEqual<T>(IList<T> arr1, IList<T> arr2)
=>
ReferenceEquals(arr1, arr2) || (
arr1 != null && arr2 != null &&
arr1.Count == arr2.Count &&
arr1.Select((a, i) => arr2[i].Equals(a)).All(i => i)
);
elementwise compare ? what about
public void Linq78a()
{
int[] numbers1 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
bool bb = numbers.Zip(numbers1, (a, b) => (a == b)).Any(p => !p);
if (!bb) Console.WriteLine("Lists are equal (bb)");
else Console.WriteLine("Lists are not equal (bb)");
}
Replace the (a==b) condition by anything you'd like to compare in a and b.
(this combines two examples from MSDN developer Linq samples)
I did this in visual studios and it worked perfectly; comparing arrays index by index with short this code.
private void compareButton_Click(object sender, EventArgs e)
{
int[] answer = { 1, 3, 4, 6, 8, 9, 5, 4, 0, 6 };
int[] exam = { 1, 2, 3, 6, 8, 9, 5, 4, 0, 7 };
int correctAnswers = 0;
int wrongAnswers = 0;
for (int index = 0; index < answer.Length; index++)
{
if (answer[index] == exam[index])
{
correctAnswers += 1;
}
else
{
wrongAnswers += 1;
}
}
outputLabel.Text = ("The matching numbers are " + correctAnswers +
"\n" + "The non matching numbers are " + wrongAnswers);
}
the output will be; The matching numbers are 7
The non matching numbers are 3
You can use Enumerable.Intersect:
int[] array1 = new int[] { 1, 2, 3, 4,5 },
array2 = new int[] {7,8};
if (array1.Intersect(array2).Any())
Console.WriteLine("matched");
else
Console.WriteLine("not matched");
I was looking to determine if two sets had equivalent contents, in any order. That meant that, for each element in set A there were equal numbers of elements with that value in both sets. I wanted to account for duplicates (so {1,2,2,3} and {1,2,3,3} should not be considered "the same").
This is what I came up with (note that IsNullOrEmpty is another static extension method that returns true if the enumerable is null or has 0 elements):
public static bool HasSameContentsAs<T>(this IEnumerable<T> source, IEnumerable<T> target)
where T : IComparable
{
//If our source is null or empty, then it's just a matter of whether or not the target is too
if (source.IsNullOrEmpty())
return target.IsNullOrEmpty();
//Otherwise, if the target is null/emtpy, they can't be equal
if (target.IsNullOrEmpty())
return false;
//Neither is null or empty, so we'll compare contents. To account for multiples of
//a given value (ex. 1,2,2,3 and 1,1,2,3 are not equal) we'll group the first set
foreach (var group in source.GroupBy(s => s))
{
//If there are a different number of elements in the target set, they don't match
if (target.Count(t => t.Equals(group.Key)) != group.Count())
return false;
}
//If we got this far, they have the same contents
return true;
}
If you don't want to compare the order but you do want to compare the count of each item, including handling null values, then I've written an extension method for this.
It gives for example the following results:
new int?[]{ }.IgnoreOrderComparison(new int?{ }); // true
new int?[]{ 1 }.IgnoreOrderComparison(new int?{ }); // false
new int?[]{ }.IgnoreOrderComparison(new int?{ 1 }); // false
new int?[]{ 1 }.IgnoreOrderComparison(new int?{ 1 }); // true
new int?[]{ 1, 2 }.IgnoreOrderComparison(new int?{ 2, 1 }); // true
new int?[]{ 1, 2, null }.IgnoreOrderComparison(new int?{ 2, 1 }); // false
new int?[]{ 1, 2, null }.IgnoreOrderComparison(new int?{ null, 2, 1 }); // true
new int?[]{ 1, 2, null, null }.IgnoreOrderComparison(new int?{ null, 2, 1 }); // false
new int?[]{ 2 }.IgnoreOrderComparison(new int?{ 2, 2 }); // false
new int?[]{ 2, 2 }.IgnoreOrderComparison(new int?{ 2, 2 }); // true
Here is the code:
public static class ArrayComparisonExtensions
{
public static bool IgnoreOrderComparison<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) =>
IgnoreOrderComparison(first, second, EqualityComparer<TSource>.Default);
public static bool IgnoreOrderComparison<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
var a = ToDictionary(first, out var firstNullCount);
var b = ToDictionary(second, out var secondNullCount);
if (a.Count != b.Count)
return false;
if (firstNullCount != secondNullCount)
return false;
foreach (var item in a)
{
if (b.TryGetValue(item.Key, out var count) && item.Value == count)
continue;
return false;
}
return true;
Dictionary<TSource, int> ToDictionary(IEnumerable<TSource> items, out int nullCount)
{
nullCount = 0;
var result = new Dictionary<TSource, int>(comparer);
foreach (var item in items)
{
if (item is null)
nullCount++;
else if (result.TryGetValue(item, out var count))
result[item] = count + 1;
else
result[item] = 1;
}
return result;
}
}
}
It only enumerates each enumerable once, but it does create a dictionary for each enumerable and iterates those once too. I'd be interested in ways to improve this.
You can also use array1.ToList().All(x => array2.Contains(x)) if you need to compare arrays which have not the same order
Check the answer to this thread which converts one of the array to a HashSet and uses SetEquals for comparison with the other array.
Note however that this does not check for order or duplicates.
List Patterns is added in C#11 .Net 7 RC2.
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers is [1, 2, 3]); // True
Console.WriteLine(numbers is [1, 2, 4]); // False
int[] a = { 2, 1, 3, 4, 5, 2 };
int[] b = { 2, 1, 3, 4, 5, 2 };
bool ans = true;
if(a.Length != b.Length)
{
ans = false;
}
else
{
for (int i = 0; i < a.Length; i++)
{
if( a[i] != b[i])
{
ans = false;
}
}
}
string str = "";
if(ans == true)
{
str = "Two Arrays are Equal";
}
if (ans == false)
{
str = "Two Arrays are not Equal";
}
//--------------Or You can write One line of Code-------------
var ArrayEquals = a.SequenceEqual(b); // returns true
This question already has answers here:
Fastest way to check if an array is sorted
(9 answers)
Closed 5 years ago.
Imagine i get two arrays as input, one of which is already sorted. I want to create a method which checks which array that is sorted and then returns it. Im not really sure how to do this
class Program
{
public double[] a = new double[] { 1, 3, 4, 8, 21, 38 };
public double[] b = new double[] { 1, 7, 19, 3, 2, 24 };
public void CheckSorting()
{
if (/* if a is sorted */)
{
return a;
}
else { /* This should be OK because if A isnt sorted then b MUST be sorted since of the arrays are always sorted in my input */
return b;
}
}
static void Main(string[] args)
{
Program checkSorting = new Program();
checkSorting.CheckSorting();
}
}
In this case, as you can see the array A should be returned as the sorted one
just.... loop over one of the arrays in a forwards direction; if the value ever goes down, that array isn't sorted
for(int i = 1 ; i < a.Length ; i++)
{
if(a[i] < a[i-1]) return b;
}
return a;
private double[] ArraySort()
{
double[] a = new double[] { 1, 3, 4, 8, 21, 38 };
double[] b = new double[] { 1, 7, 19, 3, 2, 24 };
var isOrderedAscending = a.SequenceEqual(a.OrderBy(x => x));
if (isOrderedAscending)
return a;
else
return b;
}
this method might help you,
but what has to be achieved if both or not ordered ?
I have an int[] array = {34,65,3,65,3,2,68,8,4,2}. I want to divide this array into group of 5 and find average of each subgroup.
This syntax declares (implicitly) an array of the type returned by Avg() method:
new [] { Avrg = g.Avg() } // if g.Avg() returns int, it will be int[]
if you want to declare an array of anonymous types, you must do:
new[] { new { Avrg = g.Avg() } }
EDIT:
according to your edit, this code splits the array in groups of 5 elements and computes the average of them:
int[] array = { 34, 65, 3, 65, 3, 2, 68, 8, 4, 2 };
var avgGroups = from x in Enumerable.Range(0, array.Length)
group x by (x / 5) into g
select new { Avrg = g.Average(x => array[x]) };
You don't need to give it a name; the object you are creating is of type
IEnumerable<typeof(g.Avg)>
so you can enumerate through that object to get the value of g.Avg().
Probably you want to store type in array. For this you need to have like this
var v = from xyz in new [] { new {Avg = g.Avg()} }
select xyz;
Rather use this way,
var v = from xyz in new [] { g.Avg() }
select new {Avg = xyz};
In Java, Arrays.equals() allows to easily compare the content of two basic arrays (overloads are available for all the basic types).
Is there such a thing in C#? Is there any "magic" way of comparing the content of two arrays in C#?
You could use Enumerable.SequenceEqual. This works for any IEnumerable<T>, not just arrays.
Use Enumerable.SequenceEqual in LINQ.
int[] arr1 = new int[] { 1,2,3};
int[] arr2 = new int[] { 3,2,1 };
Console.WriteLine(arr1.SequenceEqual(arr2)); // false
Console.WriteLine(arr1.Reverse().SequenceEqual(arr2)); // true
Also for arrays (and tuples) you can use new interfaces from .NET 4.0: IStructuralComparable and IStructuralEquatable. Using them you can not only check equality of arrays but also compare them.
static class StructuralExtensions
{
public static bool StructuralEquals<T>(this T a, T b)
where T : IStructuralEquatable
{
return a.Equals(b, StructuralComparisons.StructuralEqualityComparer);
}
public static int StructuralCompare<T>(this T a, T b)
where T : IStructuralComparable
{
return a.CompareTo(b, StructuralComparisons.StructuralComparer);
}
}
{
var a = new[] { 1, 2, 3 };
var b = new[] { 1, 2, 3 };
Console.WriteLine(a.Equals(b)); // False
Console.WriteLine(a.StructuralEquals(b)); // True
}
{
var a = new[] { 1, 3, 3 };
var b = new[] { 1, 2, 3 };
Console.WriteLine(a.StructuralCompare(b)); // 1
}
SequenceEqual will only return true if two conditions or met.
They contain the same elements.
The elements are in the same order.
If you only want to check if they contain the same elements regardless of their order and your problem is of the type
Does values2 contain all the values contained in values1?
you can use LINQ extension method Enumerable.Except and then check if the result has any value. Here's an example
int[] values1 = { 1, 2, 3, 4 };
int[] values2 = { 1, 2, 5 };
var result = values1.Except(values2);
if(result.Count()==0)
{
//They are the same
}
else
{
//They are different
}
And also by using this you get the different items as well automatically. Two birds with one stone.
Keep in mind, if you execute your code like this
var result = values2.Except(values1);
you will get different results.
In my case I have a local copy of an array and want to check if anything has been removed from the original array so I use this method.
For .NET 4.0 and higher you can compare elements in array or tuples via using StructuralComparisons type:
object[] a1 = { "string", 123, true };
object[] a2 = { "string", 123, true };
Console.WriteLine (a1 == a2); // False (because arrays is reference types)
Console.WriteLine (a1.Equals (a2)); // False (because arrays is reference types)
IStructuralEquatable se1 = a1;
//Next returns True
Console.WriteLine (se1.Equals (a2, StructuralComparisons.StructuralEqualityComparer));
If you would like to handle null inputs gracefully, and ignore the order of items, try the following solution:
static class Extensions
{
public static bool ItemsEqual<TSource>(this TSource[] array1, TSource[] array2)
{
if (array1 == null && array2 == null)
return true;
if (array1 == null || array2 == null)
return false;
if (array1.Count() != array2.Count())
return false;
return !array1.Except(array2).Any() && !array2.Except(array1).Any();
}
}
The test code looks like:
public static void Main()
{
int[] a1 = new int[] { 1, 2, 3 };
int[] a2 = new int[] { 3, 2, 1 };
int[] a3 = new int[] { 1, 3 };
Console.WriteLine(a1.ItemsEqual(a2)); // Output: True.
Console.WriteLine(a2.ItemsEqual(a3)); // Output: False.
Console.WriteLine(a3.ItemsEqual(a2)); // Output: False.
int[] a4 = new int[] { 1, 1 };
int[] a5 = new int[] { 1, 2 };
Console.WriteLine(a4.ItemsEqual(a5)); // Output: False
Console.WriteLine(a5.ItemsEqual(a4)); // Output: False
int[] a6 = null;
int[] a7 = null;
int[] a8 = new int[0];
Console.WriteLine(a6.ItemsEqual(a7)); // Output: True. No Exception.
Console.WriteLine(a8.ItemsEqual(a6)); // Output: False. No Exception.
Console.WriteLine(a7.ItemsEqual(a8)); // Output: False. No Exception.
}
For unit tests, you can use CollectionAssert.AreEqual instead of Assert.AreEqual.
It is probably the easiest way.
For some applications may be better:
string.Join(",", arr1) == string.Join(",", arr2)
Assuming array equality means both arrays have equal elements at equal indexes, there is the SequenceEqual answer and the IStructuralEquatable answer.
But both have drawbacks, performance wise.
SequenceEqual implementation in .Net Framework will not shortcut when the arrays have different lengths, and so it may enumerate one of them entirely, comparing each of its elements.
This said, depending on the .Net flavor (like .Net5), it may shortcut, see this comment. So for an up-to-date .Net project, SequenceEqual should be a good choice.
IStructuralEquatable is not generic and may cause boxing of each compared value. Moreover it is not very straightforward to use and already calls for coding some helper methods hiding it away.
It may be better, performance wise, to use something like:
bool ArrayEquals<T>(T[] first, T[] second)
{
if (first == second)
return true;
if (first == null || second == null)
return false;
if (first.Length != second.Length)
return false;
for (var i = 0; i < first.Length; i++)
{
if (!first[i].Equals(second[i]))
return false;
}
return true;
}
But of course, that is not either some "magic way" of checking array equality.
So currently, no, there is not really an equivalent to Java Arrays.equals() in .Net.
This LINQ solution works, not sure how it compares in performance to SequenceEquals. But it handles different array lengths and the .All will exit on the first item that is not equal without iterating through the whole array.
private static bool arraysEqual<T>(IList<T> arr1, IList<T> arr2)
=>
ReferenceEquals(arr1, arr2) || (
arr1 != null && arr2 != null &&
arr1.Count == arr2.Count &&
arr1.Select((a, i) => arr2[i].Equals(a)).All(i => i)
);
elementwise compare ? what about
public void Linq78a()
{
int[] numbers1 = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
bool bb = numbers.Zip(numbers1, (a, b) => (a == b)).Any(p => !p);
if (!bb) Console.WriteLine("Lists are equal (bb)");
else Console.WriteLine("Lists are not equal (bb)");
}
Replace the (a==b) condition by anything you'd like to compare in a and b.
(this combines two examples from MSDN developer Linq samples)
I did this in visual studios and it worked perfectly; comparing arrays index by index with short this code.
private void compareButton_Click(object sender, EventArgs e)
{
int[] answer = { 1, 3, 4, 6, 8, 9, 5, 4, 0, 6 };
int[] exam = { 1, 2, 3, 6, 8, 9, 5, 4, 0, 7 };
int correctAnswers = 0;
int wrongAnswers = 0;
for (int index = 0; index < answer.Length; index++)
{
if (answer[index] == exam[index])
{
correctAnswers += 1;
}
else
{
wrongAnswers += 1;
}
}
outputLabel.Text = ("The matching numbers are " + correctAnswers +
"\n" + "The non matching numbers are " + wrongAnswers);
}
the output will be; The matching numbers are 7
The non matching numbers are 3
You can use Enumerable.Intersect:
int[] array1 = new int[] { 1, 2, 3, 4,5 },
array2 = new int[] {7,8};
if (array1.Intersect(array2).Any())
Console.WriteLine("matched");
else
Console.WriteLine("not matched");
I was looking to determine if two sets had equivalent contents, in any order. That meant that, for each element in set A there were equal numbers of elements with that value in both sets. I wanted to account for duplicates (so {1,2,2,3} and {1,2,3,3} should not be considered "the same").
This is what I came up with (note that IsNullOrEmpty is another static extension method that returns true if the enumerable is null or has 0 elements):
public static bool HasSameContentsAs<T>(this IEnumerable<T> source, IEnumerable<T> target)
where T : IComparable
{
//If our source is null or empty, then it's just a matter of whether or not the target is too
if (source.IsNullOrEmpty())
return target.IsNullOrEmpty();
//Otherwise, if the target is null/emtpy, they can't be equal
if (target.IsNullOrEmpty())
return false;
//Neither is null or empty, so we'll compare contents. To account for multiples of
//a given value (ex. 1,2,2,3 and 1,1,2,3 are not equal) we'll group the first set
foreach (var group in source.GroupBy(s => s))
{
//If there are a different number of elements in the target set, they don't match
if (target.Count(t => t.Equals(group.Key)) != group.Count())
return false;
}
//If we got this far, they have the same contents
return true;
}
If you don't want to compare the order but you do want to compare the count of each item, including handling null values, then I've written an extension method for this.
It gives for example the following results:
new int?[]{ }.IgnoreOrderComparison(new int?{ }); // true
new int?[]{ 1 }.IgnoreOrderComparison(new int?{ }); // false
new int?[]{ }.IgnoreOrderComparison(new int?{ 1 }); // false
new int?[]{ 1 }.IgnoreOrderComparison(new int?{ 1 }); // true
new int?[]{ 1, 2 }.IgnoreOrderComparison(new int?{ 2, 1 }); // true
new int?[]{ 1, 2, null }.IgnoreOrderComparison(new int?{ 2, 1 }); // false
new int?[]{ 1, 2, null }.IgnoreOrderComparison(new int?{ null, 2, 1 }); // true
new int?[]{ 1, 2, null, null }.IgnoreOrderComparison(new int?{ null, 2, 1 }); // false
new int?[]{ 2 }.IgnoreOrderComparison(new int?{ 2, 2 }); // false
new int?[]{ 2, 2 }.IgnoreOrderComparison(new int?{ 2, 2 }); // true
Here is the code:
public static class ArrayComparisonExtensions
{
public static bool IgnoreOrderComparison<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) =>
IgnoreOrderComparison(first, second, EqualityComparer<TSource>.Default);
public static bool IgnoreOrderComparison<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
var a = ToDictionary(first, out var firstNullCount);
var b = ToDictionary(second, out var secondNullCount);
if (a.Count != b.Count)
return false;
if (firstNullCount != secondNullCount)
return false;
foreach (var item in a)
{
if (b.TryGetValue(item.Key, out var count) && item.Value == count)
continue;
return false;
}
return true;
Dictionary<TSource, int> ToDictionary(IEnumerable<TSource> items, out int nullCount)
{
nullCount = 0;
var result = new Dictionary<TSource, int>(comparer);
foreach (var item in items)
{
if (item is null)
nullCount++;
else if (result.TryGetValue(item, out var count))
result[item] = count + 1;
else
result[item] = 1;
}
return result;
}
}
}
It only enumerates each enumerable once, but it does create a dictionary for each enumerable and iterates those once too. I'd be interested in ways to improve this.
You can also use array1.ToList().All(x => array2.Contains(x)) if you need to compare arrays which have not the same order
Check the answer to this thread which converts one of the array to a HashSet and uses SetEquals for comparison with the other array.
Note however that this does not check for order or duplicates.
List Patterns is added in C#11 .Net 7 RC2.
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers is [1, 2, 3]); // True
Console.WriteLine(numbers is [1, 2, 4]); // False
int[] a = { 2, 1, 3, 4, 5, 2 };
int[] b = { 2, 1, 3, 4, 5, 2 };
bool ans = true;
if(a.Length != b.Length)
{
ans = false;
}
else
{
for (int i = 0; i < a.Length; i++)
{
if( a[i] != b[i])
{
ans = false;
}
}
}
string str = "";
if(ans == true)
{
str = "Two Arrays are Equal";
}
if (ans == false)
{
str = "Two Arrays are not Equal";
}
//--------------Or You can write One line of Code-------------
var ArrayEquals = a.SequenceEqual(b); // returns true
Lets say I have this array,
int[] numbers = {1, 3, 4, 9, 2};
How can I delete an element by "name"? , lets say number 4?
Even ArrayList didn't help to delete?
string strNumbers = " 1, 3, 4, 9, 2";
ArrayList numbers = new ArrayList(strNumbers.Split(new char[] { ',' }));
numbers.RemoveAt(numbers.IndexOf(4));
foreach (var n in numbers)
{
Response.Write(n);
}
If you want to remove all instances of 4 without needing to know the index:
LINQ: (.NET Framework 3.5)
int[] numbers = { 1, 3, 4, 9, 2 };
int numToRemove = 4;
numbers = numbers.Where(val => val != numToRemove).ToArray();
Non-LINQ: (.NET Framework 2.0)
static bool isNotFour(int n)
{
return n != 4;
}
int[] numbers = { 1, 3, 4, 9, 2 };
numbers = Array.FindAll(numbers, isNotFour).ToArray();
If you want to remove just the first instance:
LINQ: (.NET Framework 3.5)
int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIndex = Array.IndexOf(numbers, numToRemove);
numbers = numbers.Where((val, idx) => idx != numIndex).ToArray();
Non-LINQ: (.NET Framework 2.0)
int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIdx = Array.IndexOf(numbers, numToRemove);
List<int> tmp = new List<int>(numbers);
tmp.RemoveAt(numIdx);
numbers = tmp.ToArray();
Edit: Just in case you hadn't already figured it out, as Malfist pointed out, you need to be targetting the .NET Framework 3.5 in order for the LINQ code examples to work. If you're targetting 2.0 you need to reference the Non-LINQ examples.
int[] numbers = { 1, 3, 4, 9, 2 };
numbers = numbers.Except(new int[]{4}).ToArray();
You can also convert your array to a list and call remove on the list. You can then convert back to your array.
int[] numbers = {1, 3, 4, 9, 2};
var numbersList = numbers.ToList();
numbersList.Remove(4);
The code that is written in the question has a bug in it
Your arraylist contains strings of " 1" " 3" " 4" " 9" and " 2" (note the spaces)
So IndexOf(4) will find nothing because 4 is an int, and even "tostring" would convert it to of "4" and not " 4", and nothing will get removed.
An arraylist is the correct way to go to do what you want.
I posted my solution here.
This is a way to delete an array element without copying to another array - just in frame of the same array instance:
public static void RemoveAt<T>(ref T[] arr, int index)
{
for (int a = index; a < arr.Length - 1; a++)
{
// moving elements downwards, to fill the gap at [index]
arr[a] = arr[a + 1];
}
// finally, let's decrement Array's size by one
Array.Resize(ref arr, arr.Length - 1);
}
Removing from an array itself is not simple, as you then have to deal with resizing. This is one of the great advantages of using something like a List<int> instead. It provides Remove/RemoveAt in 2.0, and lots of LINQ extensions for 3.0.
If you can, refactor to use a List<> or similar.
Balabaster's answer is correct if you want to remove all instances of the element. If you want to remove only the first one, you would do something like this:
int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int firstFoundIndex = Array.IndexOf(numbers, numToRemove);
if (numbers >= 0)
{
numbers = numbers.Take(firstFoundIndex).Concat(numbers.Skip(firstFoundIndex + 1)).ToArray();
}
As a generic extension, 2.0-compatible:
using System.Collections.Generic;
public static class Extensions {
//=========================================================================
// Removes all instances of [itemToRemove] from array [original]
// Returns the new array, without modifying [original] directly
// .Net2.0-compatible
public static T[] RemoveFromArray<T> (this T[] original, T itemToRemove) {
int numIdx = System.Array.IndexOf(original, itemToRemove);
if (numIdx == -1) return original;
List<T> tmp = new List<T>(original);
tmp.RemoveAt(numIdx);
return tmp.ToArray();
}
}
Usage:
int[] numbers = {1, 3, 4, 9, 2};
numbers = numbers.RemoveFromArray(4);
You can do in this way:
int[] numbers= {1,3,4,9,2};
List<int> lst_numbers = new List<int>(numbers);
int required_number = 4;
int i = 0;
foreach (int number in lst_numbers)
{
if(number == required_number)
{
break;
}
i++;
}
lst_numbers.RemoveAt(i);
numbers = lst_numbers.ToArray();
' To remove items from string based on Dictionary key values.
' VB.net code
Dim stringArr As String() = "file1,file2,file3,file4,file5,file6".Split(","c)
Dim test As Dictionary(Of String, String) = New Dictionary(Of String, String)
test.Add("file3", "description")
test.Add("file5", "description")
stringArr = stringArr.Except(test.Keys).ToArray()
public int[] DeletePart(int position, params int[] numbers)
{
int[] result = new int[numbers.Length - 1];
int z=0;
for (int i = 0; i < numbers.Length; i++)
{
if (position - 1 != i)
{
result[z] = numbers[i];
z++;
}
}
return result;
}
We can delete array elements by using for loops and continue statements:
string[] cars = {"volvo", "benz", "ford", "bmw"};
for (int i = 0; i < cars.Length; i++)
{
if (cars[i] == "benz")
{
continue;
}
Console.WriteLine(cars[i]);
}