How to convert enum to list with where statement - c#

I need to get values from enum which is not equal to 1 and display them in to dropdown list.
I mean is that, I do not want to show Done and it's value.
public enum Statement
{
Done= 1,
Waiting= 2,
Rejected= 3
}

You can use Enum.GetValues with LINQ like:
List<string> list = Enum.GetValues(typeof(Statement))
.Cast<Statement>()
.Where(r=> (int) r != 1)
.Select(t=> t.ToString())
.ToList();

Related

Check if at least two element in array are equal

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

How to perform LINQ query over Enum?

Below is my Enumerator List:
public enum StatusEnum
{
Open = 1,
Rejected = 2,
Accepted = 3,
Started = 4,
Completed = 5,
Cancelled = 6,
Assigned = 7
}
I need to bind this to a Combobox, but, only show a few specific statuses and ignore the rest.
This is what I have so far:
public static List<Activity.StatusEnum> StatusList()
{
IEnumerable<Activity.StatusEnum> query = Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>()
.Where(x => x == Activity.StatusEnum.Open
|| x == Activity.StatusEnum.Rejected
|| x == Activity.StatusEnum.Accepted
|| x == Activity.StatusEnum.Started);
return query.ToList();
}
However, I feel that the code is little messy and is not a correct approach to bind filtered Enum list to a Combobox.
Can anyone suggest a more robust way of doing this?
Update
I might need to change the Order of selection. So I need a generic solution which doesn't only get the first X number of statuses.
return Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>().Where((n, x) => x < 4);
If you want to be able to change the list of items, just add them into a List<Activity.StatusEnum> and use Contains:
var listValid = new List<Activity.StatusEnum>() { Activity.StatusEnum.Open, Activity.StatusEnum.Rejected, Activity.StatusEnum.Accepted, Activity.StatusEnum.Started };
return Enum.GetValues(typeof(Activity.StatusEnum)).Cast<Activity.StatusEnum>().Where(n => listValid.Contains(n));
Well if you're going to hard code the items that should be in the list anyway, why not just do this:
public static List<Activity.StatusEnum> StatusList()
{
return new List<Activity.StatusEnum>
{
Activity.StatusEnum.Open,
Activity.StatusEnum.Rejected,
Activity.StatusEnum.Accepted,
Activity.StatusEnum.Started
};
}
You could also dispose of the List<T> and just return the array itself. As long as you know these are the items you want, then there's no need for Linq.
Steps:
Get the enum values and cast the results to the type of the enum
Sort the enum values by their integer values (otherwise they sort
naturally by unsigned magnitude)
Take the first 4
Code:
return Enum.GetValues(typeof(Activity.StatusEnum))
.Cast<Activity.StatusEnum>()
.OrderBy(se =>(int)se)
.Take(4);
Output:
Open Rejected Accepted Started
First, if possible, I'd make your enum values powers of 2, so they could be OR'd together.
public enum StatusEnum
{
Open = 1,
Rejected = 2,
Accepted = 4,
Started = 8,
Completed = 16,
Cancelled = 32,
Assigned = 64
}
Then you could do something like this:
public static List<Activity.StatusEnum> StatusList()
{
var statusesToShow = Activity.StatusEnum.Open | Activity.StatusEnum.Rejected | Activity.StatusEnum.Accepted | Activity.StatusEnum.Started;
return Enum
.GetValues(typeof(Activity.StatusEnum))
.Cast<Activity.StatusEnum>()
.Where(x => (x & statusesToShow) == x)
.ToList();
}
EDIT: In light of the fact that you can't change the enum values, I'd just recommend you use something like:
public static List<Activity.StatusEnum> StatusList()
{
return new List<Activity.StatusEnum> {
Activity.StatusEnum.Open,
Activity.StatusEnum.Rejected,
Activity.StatusEnum.Accepted,
Activity.StatusEnum.Started
};
}
". . . only show the first 4 statuses and ignore the rest."
To get the first n elements of an IEnumerable<T>, use the Take method:
return Enum.GetValues(typeof(Activity.StatusEnum))
.Cast<Activity.StatusEnum>()
.Take(4)
.ToList();
How about something along the lines of:
.Where(x => x <= Activity.StatusEnum.Started)

Using LINQ how can I check for an instance of a number in one array, in another array?

I have a list of MyItem objects called myItems like this:
public class MyItem{
public int[] category_ids;
public string name;
}
List<MyItem> myItems;
I want to filter down the list of objects with a list of selected categories so that the filtered list contains ANY of the filter category ids:
int[] filter = { 1, 5, 6, 9 };
How would I do that using LINQ in one line? (if its even possible, I cant wrap my head around it!)
I imagine something along the lines of:
IEnumerable<MyItem> filtered = myItems.Where(item => item.category_ids.Contains(xxx));
var filtered = myItems.Where(x => x.category_ids.Intersect(filter)
.Any());
Needs one more method call:
IEnumerable<MyItem> filtered = myItems.Where(item => item.category_ids.Any(x=>filter.Contains(x));
Another option than the one already presented:
var filtered = myItems.Where( item => item.category_ids.Intersect( filter ).Count() > 0 );

Getting a cell from DataTable.Row.ItemArray with Linq

I have the following ItemArray:
dt.Rows[0].ItemArray.. //{0,1,2,3,4,5}
the headers are : item0,item1,item2 etc..
So far, to get a value from the ItemArray I used to call it by an index.
Is there any way to get the value within the ItemArray with a Linq expression based on the column name?
Thanks
You can also use the column-name to get the field value:
int item1 = row.Field<int>("Item1");
DataRow.Item Property(String)
DataRow.Field Method: Provides strongly-typed access
You could also use LINQ-to-DataSet:
int[] allItems = (from row in dt.AsEnumerable()
select row.Field<int>("Item1")).ToArray();
or in method syntax:
int[] allItems = dt.AsEnumerable().Select(r => r.Field<int>("Item1")).ToArray();
If you use the Item indexer rather than ItemArray, you can access items by column name, regardless of whether you use LINQ or not.
dt.Rows[0]["Column Name"]
Tim Schmelter's answer is probably what you are lookin for, just to add also this way using Convert class instead of DataRow.Field:
var q = (from row in dataTable.AsEnumerable() select Convert.ToInt16(row["COLUMN1"])).ToArray();
Here's what I've come up with today solving a similar problem. In my case:
(1)I needed to xtract the values from columns named Item1, Item2, ... of bool type.
(2) I needed to xtract the ordinal number of that ItemN that had a true value.
var itemValues = dataTable.Select().Select(
r => r.ItemArray.Where((c, i) =>
dataTable.Columns[i].ColumnName.StartsWith("Item") && c is bool)
.Select((v, i) => new { Index = i + 1, Value = v.ToString().ToBoolean() }))
.ToList();
if (itemValues.Any())
{
//int[] of indices for true values
var trueIndexArray = itemValues.First().Where(v => v.Value == true)
.Select(v => v.Index).ToArray();
}
forgot an essential part: I have a .ToBoolean() helper extension method to parse object values:
public static bool ToBoolean(this string s)
{
if (bool.TryParse(s, out bool result))
{
return result;
}
return false;
}

Get min value in row during LINQ query

I know that I can use .Min() to get minimum value from column, but how to get minimum value in a row?
I have following LINQ query (for testing purposes):
from p in Pravidloes
where p.DulezitostId == 3
where p.ZpozdeniId == 1 || p.ZpozdeniId == 2
where p.SpolehlivostId == 2 || p.SpolehlivostId == 3
group p by p.VysledekId into g
select new {
result = g.Key,
value = g
}
Which results into this:
I would however like to get only the MIN value of following three columns:
DulezitostId, ZpozdeniId, SpolehlivostId as a value in:
select new {
result = g.Key,
value = g // <-- here
}
The final result then should look like:
result: 2, value: 1
result: 3, value: 2
I have been looking for similar questions here and googled for few examples with grouping and aggregating queries, but found nothing that would move me forward with this problem.
Btw: Solution isn't limited to linq, if you know better way how to do it.
You could create an array of the values and do Min on those.
select new {
result = g.Key,
value = g.SelectMany(x => new int[] { x.DulezitostId, x.ZpozdeniId, x.SpolehlivostId }).Min()
}
This will return the min for those 3 values in each grouping for ALL rows of that grouping.
Which would result in something like this...
result: 3, value: 1
The below will select the min for each row in the grouping...
select new {
result = g.Key,
value = g.Select(x => new int[] { x.DulezitostId, x.ZpozdeniId, x.SpolehlivostId }.Min())
}
Which would result in something like this...
result: 3, value: 1, 2
The best solution if you're using straight LINQ is Chad's answer. However, if you're using Linq To SQL it won't work because you can't construct an array like that.
Unfortunately, I believe the only way to do this in Linq To Sql is to use Math.Min repeatedly:
select new {
result = g.Key,
value = Math.Min(Math.Min(DulezitostId, ZpozdeniId), SpolehlivostId)
}
This will generate some ugly CASE WHEN ... statements, but it works.
The main advantage of doing it this way is that you're only returning the data you need from SQL (instead of returning all 3 columns and doing the Min in the application).

Categories