Filter Enums based on List in LINQ - linq

I Have a Enum
public enum ProcessStatus: byte
{
NotStarted = 0,
PreCheckStarted= 1,
PreCheckCompleted= 2,
Processing= 3,
Failed= 4,
Completed= 5,
Closed= 6
}
in Table we have entries like 0,3,5,6
we need list of Enums based on some criteria and criteria is List which contains 0,1,2
i am able to get all Enums as List Like
Enum.GetValues(typeof(ProcessStatus)).OfType<ProcessStatus>()
and have
List<byte> processListIDs
which contains IDs
i want
IEnumerable<ProcessStatus> filtered based on ids in processListIDs using LINQ.
Thanks in Advance

You can use Intersect with better performance:
var enumList = Enum.GetValues(typeof (ProcessStatus))
.OfType<ProcessStatus>().Cast<byte>();
var result = enumList.Intersect(processListIDs)
.Cast<ProcessStatus>();

var res =
processStatusCollection.Where(item => processListIDs.Contains((int)item));

You could use Enum.TryParse<TEnum>:
List<byte> processListIDs = new List<byte>() { 0, 3, 5, 6 };
ProcessStatus ps = ProcessStatus.NotStarted;
IEnumerable<ProcessStatus> status = processListIDs
.Where(p => Enum.TryParse<ProcessStatus>(p.ToString(), out ps))
.Select(p => ps);

Try this,
var p = new List<byte>() { 1, 2, 3, 4, 6 };
IEnumerable<ProcessStatus> result = p.Select(o => (ProcessStatus)Enum.Parse(typeof(ProcessStatus), o.ToString()));
/// do something with result

Related

Rxjs distinct and arrays of numbers

I can't explain to myself this
const something = new Rx.BehaviorSubject([1,2,4,4])
.distinct()
.do((s) => console.log(s))
.map(list => list.length)
.filter(length => length >=2)
.subscribe(total => console.log('total:', total));
this is what I get as output
[1, 2, 4, 4]
"total:"
4
I get confused because reviewing the docs on distinct I thought it would work for numbers. My use case is a data table widget sends me events and this array tracks which row they clicked and I want to detect once a double click occurred.
updated code
const something = new Rx.BehaviorSubject([]);
something.next([1]);
console.log(something.getValue());
something.next(something.getValue().concat(2));
something.next(something.getValue().concat(3));
something.next(something.getValue().concat(4));
something.next(something.getValue().concat(4));
something
.distinct()
.subscribe(val => console.log('value:', val));
output
"value:"
[1, 2, 3, 4, 4]
You're sending a value that happens to be an array. You would see the operation of distinct if you did
const something = new Rx.BehaviorSubject([]);
something .distinct() .subscribe(val => console.log('value:', val));
something.next(1); // --> value: 1
something.next(2); // --> value: 2
something.next(1); // no output (because of distinct)
something.next(3); // --> value: 3

Filter LINQ query using items from an external list with Lambda

How do you rewrite this in lambda?
int[] productList = new int[] { 1, 2, 3, 4 };
var myProducts = from p in db.Products
where productList.Contains(p.ProductID)
select p;
Assuming that by "with lambda" you mean the "query syntax", you can rewrite your query like this:
var myProducts = db.Products.Where(p => productList.Contains(p.ProductID));
Same thing just move the logic within a Where call.
var myProducts = db.Products.Where(p => productList.Contains(p.ProductID));
http://msdn.microsoft.com/en-us/library/vstudio/bb397947.aspx
^ a quick read that compares query syntax to method syntax for a query to two.

LINQ Get Grouped ID by condition

Hi I have a List so:
A 1
A 2
A 3
A 4
B 1
B 2
C 1
I want to select the letter that contains AT LEAST these 3 numbers: 1,2,3
So in this case would be selected the letter A.
Can you help me to write this as LINQ expression?
Thanks a lot!
First, make a collection of the numbers you require.
var required = new[] { 1, 2, 3 };
Then, group your pairings by letter.
var groupedPairings = pairings.GroupBy(p => Letter, p => Number);
Then, discard those pairings that don't have your three required items. (The logic here is "take the collection of required items, remove anything in the group, and make sure there is nothing left".)
var groupsWithRequired = groupedPairings
.Where(g => !required.Except(g).Any());
Now, if you just want the letters, you can simply do
var lettersWithRequired = groupsWithRequired.Select(g => g.Key);
or if you want a dictionary mapping from the letter to its collection of numbers, you can do
var dictionary = groupsWithRequired.ToDictionary(g => g.Key, g => g.ToArray());
var numbersForA = dictionary["A"]; // = {1, 2, 3, 4}
You could try this, although I don't feel it's the best answer:
var items = new List<Item>{
new Item{Name="A", Value=1},
new Item{Name="A", Value=2},
new Item{Name="A", Value=3},
new Item{Name="A", Value=3},
new Item{Name="A", Value=4},
new Item{Name="B", Value=1},
new Item{Name="B", Value=2},
new Item{Name="C", Value=1},
};
var values = new List<int>{1,2,3};
var query = items.GroupBy (i => i.Name)
.Where (i => i.Select (x => x.Value)
.Intersect(values).Count() == values.Count)
.Select (i => i.Key);
Where
class Item{
public string Name{get;set;}
public int Value{get;set;}
}

Linq To Entities Get 2nd Last entry In List

I have the following code which returns a list of Objects.
var listOfLogins = _logService.GetLogEventsByItemID(137).ToList();
I would like to get the 2nd last object in this list.
Does anyone know how to do this using Linq to Entities?
Thanks.
var secondlast = _logService.GetLogEventsByItemID(137)
.Reverse()
.Skip(1)
.Take(1)
.FirstOrDefault();
Update
#Dherik makes a good point in his comment that .Reverse is not actually supported in LINQ to Entities and will result in the query being evaluated at the point of calling reverse, rather than at the point of calling .FirstOrDefault. See here for all (not) supported methods.
The alternative (LINQ to Entities friendly) solution requires that you have a suitable field to order by (which must be the case anyway otherwise "second last" has no relevance):
var secondlast = _logService.GetLogEventsByItemID(137)
.OrderByDescending(e => e.EventDate /* could be any db field */)
.Skip(1)
.Take(1)
.FirstOrDefault();
int[] items = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int item = items.Skip(items.Count() - 2).Take(1).Single();
//will return 9
like this?

linq in or contains?

How can I use Linq-to-sql to a search like this:
where obj.id equals any of the following {1,2,3,4}
I would guess I could use the in or perhaps contains?
where obj.id in Enumerable.Range( (int) myEnum.Start, (int) myEnum.End) ) ?
You can use .Contains(), like this:
var list = new List<int> { 1, 2, 3, 5 };
var result = from s in DB.Something
where list.Contains(s.Id)
select s;
This will get translated to a parameterized form of:
WHERE Id IN (1, 2, 3, 5)
var myCustomers = new short[] {1,2,3,4};
var foo = db.Customers.Where(c=> myCustomers.Contains(c.ID));

Resources