Check if at least two element in array are equal - c#

Is there a way to check that at least one element appears more than once in an array are equal without sequentially comparing every element.
Example: In int[] array1 = { 1, 3, 4, 2, 4 }; the element 4 appears twice.

You just need to check if there is any difference between original array and it's Distinct() version.
var result = (array1.Count()-array1.Distinct().Count())>0;

You can use Distinct() method to get unique values of array and compare length with original array
int[] arrayDistinctElements = array1.Distinct().ToArray();
if(arrayDistinctElements.length == array1.length)
{
//All unique elements
}
else
{
//Duplicates were present
}

This might do the trick for you
var duplicates = array1.GroupBy(p => p).Where(g => g.Count() > 1).Select(g => g.Key);
variable duplicates contains the list of repeated items
EDIT
If you want to the return value to be Boolean than
var duplicates = array1.GroupBy(p => p).Where(g => g.Count() > 1).Select(g => g.Key).Count() > 0;
You can also do something like this
if(array1.Distinct().Count() != array1.Count())
return true; /// You have duplicates in the array
else
return false; /// All the elements in the array are different

You can use the following code:
var isExisted = list.Count(item => item.Param == "test") >= 2;
Sample solution in your case: https://dotnetfiddle.net/1y4w9K

Related

Get every nth element or last

I'm hitting a brick wall with this, and I just can't seem to wrap my head around it.
Given a List of objects, how can i get every third element starting from the end (so the third to last, sixth to last etc) but if it gets to the end and there are only 1 or 2 left, returns the first element.
I'm essentially trying to simulate drawing three cards from the Stock and checking for valid moves in a game of patience, but for some reason i'm struggling with this one concept.
EDIT:
So far I've tried looked into using the standard for loop increasing the step. That leads me to the second need which is to get the first element if there are less than three on the final loop.
I've tried other suggestions on stack overflow for getting nth element from a list, however they all also don't provide the second requirement.
Not entirely sure what code i could post that wouldn't be a simple for loop. as my problem is the logic for the code, not the code itself.
For example:
Given the list
1,2,3,4,5,6,7,8,9,10
i would like to get a list with
8, 5, 2, 1
as the return.
pseudocode:
List<object> filtered = new List<object>();
List<object> reversedList = myList.Reverse();
if(reversedList.Count % 3 != 0)
{
return reversedList.Last();
}
else
{
for(int i = 3; i < reversedList.Count; i = i +3)
{
filterList.Add(reversedList[i]);
}
if(!filterList.Contains(reversedList.Last())
{
filterList.Add(reversedList.Last());
}
Try using this code -
List<int> list = new List<int>();
List<int> resultList = new List<int>();
int count = 1;
for (;count<=20;count++) {
list.Add(count);
}
for (count=list.Count-3;count>=0;count-=3)
{
Debug.Log(list[count]);
resultList.Add(list[count]);
}
if(list.Count % 3 > 0)
{
Debug.Log(list[0]);
resultList.Add(list[0]);
}
Had to try and do it with linq.
Not sure if it live up to your requirements but works with your example.
var list = Enumerable.Range(1, 10).ToList();
//Start with reversing the order.
var result = list.OrderByDescending(x => x)
//Run a select overload with index so we can use position
.Select((number, index) => new { number, index })
//Only include items that are in the right intervals OR is the last item
.Where(x => ((x.index + 1) % 3 == 0) || x.index == list.Count() - 1)
//Select only the number to get rid of the index.
.Select(x => x.number)
.ToList();
Assert.AreEqual(8, result[0]);
Assert.AreEqual(5, result[1]);
Assert.AreEqual(2, result[2]);
Assert.AreEqual(1, result[3]);

stating which conditions have been matched in linq where

I have a linq statement as such
dbContext.Items
.Where(
p =>
(p.Client.Contact != null && p.Client.Contact.Firstname.ToLower().Contains(searchText.ToLower()))
||
(p.Client.Contact != null && p.Client.Contact.Surname.ToLower().Contains(searchText.ToLower()))
||
(p.PolicyNumber != null && p.PolicyNumber.ToLower().Contains(searchText.ToLower()))
||
(
p.PolicyLivesAssureds
.Where(
pl =>
pl.Contact != null && pl.Contact.Firstname.ToLower().Contains(searchText.ToLower())
|| pl.Contact.Surname.ToLower().Contains(searchText.ToLower())
).Count() > 0
)
)
).OrderBy(p => p.IeUtem);
This is actually needed in an autocomplete. What I want to do is being able to know exactly which among my 5 conditions has been matched and display the particular item that has been matched. For example say that PolicyNumber has been matched i want to send only policynumber for that row and for others if name has been matched i want to send only the name for that row.
Is there a way to do this;
This is a bit more of a food for thought answer as it has flaws in it's approach, but I think it does solve your problem:
double[] items = { 1, 2, 3, 4, 5 };
IEnumerable<Tuple<double, int>> results = items.Select(x =>
{
int index = 0;
foreach (var condition in new Func<bool>[]
{
// TODO: Write conditions here.
() => x == 1,
() => x == 2
})
{
if (condition() == true)
return index;
else
index++;
}
return -1;
}).Zip(items, (matchedCondtion, item) => Tuple.Create(item, matchedCondtion))
.Where(x => x.Item2 != -1);
I've used a simple double array as an example of the collection to filter, but it's just an example, you can use anything.
The first select returns an integer for each element in the collection. If there is a condition match, it returns the index of the condition. If there is not match it returns -1.
It does this by enumerating over the Func collection and returning the index of the first true condition (emulating the short circuiting of the || operator). If no conditions match it simply returns -1 after evaluating all conditions.
These results are then zipped back up with the original collection (using a Tuple), mapping each element with the index of its matching condition (or -1).
So the example would return:
{ 1, 0 },
{ 2, 1 },
{ 3, -1 },
{ 4, -1 },
{ 5, -1 }
This result is then simply filtered using Where to remove any entries with -1, leaving you with a collection of elements that matched a condition and the index of the condition that matched (in the form of a Tuple).
So to customize this for your solution, you can remove the example conditions and place whatever number of conditions you want at:
// TODO: Write conditions here.
The question becomes how do you want to know which queries match. For example you could do something like this
class AutoCompleteItem {
String Text {get; set;}
Item Item {get; set;}
}
var firstNames = dbContext.Items.Select(p => new AutoCompleteItem { Name = p.Client.Contract.FirstName, Item = p})
var lastNames = dbContext.Items.Select(p => new AutoCompleteItem { Name = p.Client.Contract.SurName, Item = p})
var result = firstName.Union(lastNames).Where(p => p.Name.Contains(searchText)).OrderBy(a => a.Item.IeUtem);
Now AutcompleteItem is a class that contains the text you want (and possibly any other fields you need, like information which field it was that matched)
The Idea here is the MVVM patttern. You have your model (the items). Now you need to construct a viewModel (AutoCompleteItems) that actual aids you in displaying what you want.

Find first free element

I looking for query which return first number not available in list
int[] list = new int[] { 1,4,2,5,6,7 };
For above example I expect to have result 3.
Perhaps something like this:
int result = Enumerable.Range(1, list.Length)
.Where(i => !list.Contains(i))
.FirstOrDefault();
This will return 0 if list contains all integers from 1 to n.
var first = Enumerable.Range(1, list.Max()).Except(list).First();

How to find an index of an element from a list<string>, an element contains a specific part [duplicate]

This question already has answers here:
Get index of lines that match my linq
(3 answers)
Closed 9 years ago.
I have a List, which contains.
1. This is house.
2. I am writing with pen.
Now I want to know that at what index the string contains house(1.)
How to do that without for loop? Array.IndexOf will not work as it will not find element with same match
to find the first index:
var idx = myList.FindIndex(x => x.Contains("abc"));
An elegant way is to use FindIndex
List<String> exampleList = new List<String>();
exampleList.Add("This is a house.");
exampleList.Add("I am writing with pen");
int index = exampleList.FindIndex(x => x.Contains("house"));
Console.WriteLine(index); //0
index = exampleList.FindIndex(x => x.Contains("pen"));
Console.WriteLine(index); //1
FindIndex searches for an element that matches the conditions defined
by a specified predicate, and returns the zero-based index of the
first occurrence within the List or a portion of it.
var indexes = Enumerable.Range(0, list.Length)
.Where(index => list[index].Contains("1."));
Clean and simple
string[] data = { "This is house", "I am writing with pen." };
List<string> list = new List<string>(data);
int index = list.FindIndex(str => str.Contains("house"));
string key = "house";
var result = yourlist.Select((x,y)=>new{ListIndex = y, ElementIndex = x.IndexOf(key)})
.Where(x=>x.ElementIndex > -1)
.ToList();
With this code you'll have as result a collection of an Anonymous type, with 2 properties: the first one with the index of the list, and the second one with the index inside the string
int index = Array.FindIndex(list.ToArray(), i => i.Contains("house") );
myList.FindIndex(x => x.ToLower().Contains("house"))
That is the solution if you want to search in a case-insensitive manner.

Selecting index of array that has a value larger than a threshold

I have an array of doubles and a threshold value.
I would like to select the first index in my array where the value at the index is larger than the threshold.
How the do I accomplish that in LINQ?
I got it to work with:
var n = acc_avg.Select((val, index) => new {Val = val, Index = index})
.Where(l => l.Val > threshold)
.First()
.Index
But is there is better way?
You can use Array.FindIndex:
var n = Array.FindIndex(acc_avg, x => x > threshold);
Your solution looks pretty decent to me, but I believe it will throw an exception if there are no elements in the sequence that meet your criteria. I'd consider FirstOrDefault instead of First and test for null before accessing.
var n = acc_avg.Select((val,index) => new {Val= val, Index = index}).Where(l=> l.Val > threshold).FirstOrDefault();
if(n != null)
DoSomething(n.Index);
Of course, if your object already had an index property (or if the location in the sequence isn't important to you) you could shorten this to:
var n = acc_avg.FirstOrDefault(l => l > threshold);
But you probably knew that. :)

Categories