Comparing Arrays LINQ - c#

How can I compare to array in linq and get all elements where there is at least one intersection?
Example:
selectes = {1,5,7}
Bands[0].SongsID {1,9}
Bands[1].SongsID {5,6}
Bands[2].SongsID {4,6}
I need to select Bands[0] and Bands[1].
I tried this:
var selectes2 = Bands.Where(t => t.SongsID.Intersect(selectes));
Bands class:
public class Band
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime YearOfCreate { get; set; }
public string Country { get; set; }
public int[] SongsID { get; set; }
}

var selectes2 = Bands.Where(t => t.SongsID.Intersect(selectes).Any());

Assuming you mean to select any band that has any song ID that matches your list of ids, you could accomplish that with this:
var matchingBands = Bands.Where(band => band.SongsID.Any(selectes.Contains));

Related

C# LINQ multiple arrays to simple list of objects

I have an array of objects List<SlovnikWords>, here is the model:
class SlovnikWord
{
public int Id { get; set; } = -1;
public string Title { get; set; }
public string Description { get; set; }
public List<Word> Forms { get; set; }
...
}
And the model for Word is as follows
class Word
{
public int Id { get; set; } = -1;
public string Title { get; set; }
public string Description { get; set; }
...
}
I need to create a list of all the Forms from all the original list of SlovnikWords, here's what I came up with:
var q = SlovnikData.Select(x => x.Forms);
This unfortunately creates an array of arrays, where as I only need one dimensional array of Forms without the outer one, i.e. a compound of x.Forms, please help.
This should do it:
var q = SlovnikData.SelectMany(x => x.Forms);

Distinct on multiple fields

I Have a List of some Properties as Model
public class AnswerList {
public int ID { get; set; }
public int? Schedule_ID { get; set; }
public int? SubItemID { get; set; }
public string SubItemName { get; set; }
public string ItemName { get; set; }
public string Answer { get; set; }
public string Remarks { get; set; }
public string Remarks_Flag { get; set; }
public string Lattitude { get; set; }
public string Longitude { get; set; }
public DateTime? Load_Date { get; set; }
}
I was getting list of Distinct Sub Items from this List
List<string> sub_item_list = AnswerList.Select(x => x.SubItemName).Distinct().ToList();
Now I want data in different format as per below class
public class SubItemList {
public string ItemName { get; set; }
public string SubItemName { get; set; }
}
My requirement is to get distinct sub item with their respective Item Names , Sub Item should be distinct but Item Name can be repeated as one Item can contain multiple Subitem
Distinct Does not work on multiple values so I tried
List<SubItemList> SI_List =
AnswerList.GroupBy(d => d.SubItemID)
.Select(x =>
new SubItemList
{
ItemName = x.Select(a => a.ItemName).First(),
SubItemName = x.Select(a => a.SubItemName).First()
}).Distinct().ToList();
This way I am getting what I want but I don't think its a preferable approach ,
Linq expression inside another Linq expression
How can I get it with a simple Linq expression ?
I am using ASP.Net Core 2.0
If the expectation is what you have asked in the question, then following shall be the query:
AnswerList.GroupBy(d => new { d.SubItemID, d.ItemName, d.SubItemName})
.Select(x => new SubItemList{
ItemName = x.Key.ItemName,
SubItemName =x.Key.SubItemName
}
).Distinct();
How it works
GroupBy unique combination of SubItemID, ItemName, SubItemName, which will form the grouping key
Now only Pick the ItemName, SubItemName to create SubItemList and call Distinct to remove duplicates even across SubItemID
For Distinct to work correctly for the class SubItemList either implement IEquatable<SubItemList> or supply the IEqualityComparer<SubItemList> to the Distinct
Try with
GroupBy(
p => new {p.ItemName, p.SubItemName}
).Select(g => new { g.Key.ItemName, g.Key.SubItemName });

c# Linq Method with GroupBy and Select

I have the following model:
public class HeadCount
{
public int Id { get; set; }
public int ContractId { get; set; }
public string FiscalYear { get; set; }
public string TaskOrder { get; set; }
public decimal ContractHours { get; set; }
public int PersonId { get; set; }
public string CompanyName { get; set; }
public string UserId { get; set; }
public int ClinAssignId { get; set; }
}
Using standard sql, I have the following script I run in SSMS:
select personid, sum(contracthours) as hours from headcounts where personid != 0 group by personid
I am stubbling trying to convert this to a LINQ menthod call. This is what I tried:
var results = _context.HeadCounts
.GroupBy(p => p.PersonId)
.Select(n => new {personid = n.Key, hours = n.Sum(ContractHours)});
It does not like the ContractHours in the Sum. I have even tried n.ContractHours
What am I doing wrong?
Sum takes a selector if the collection is not a primitive numeric collection, so you need:
n.Sum(p => p.ContractHours)
Thanks to Robs comment in the original question, this was the answer I was looking for.

Find a particular element in List<> and fetch whole data of that row if element is found

I have a List<> which contains collection of objects after getting this list of BillSheetDetail I want to find that billWorkDetails[].details_classification =="xyz" and if it is found then fetch all the data of that particular array index of billWorksDetails[] and store it in other array to display.
How can I do this? I am new to C#
public class BillSheetDetail
{
public DateTime creation_date { get; set; }
public string customer_name { get; set; }
public string subject { get; set; }
public decimal tax_rate { get; set; }
public int total_amount { get; set; }
public string special_instruction { get; set; }
public string comment { get; set; }
public List<BillWorkDetail> billWorkDetails { get; set; }
}
[Serializable]
public class BillWorkDetail
{
public string product_name { get; set; }
public decimal quantity { get; set; }
public string unit { get; set; }
public int unit_cost { get; set; }
public int amount { get; set; }
public string remarks { get; set; }
public int row_no { get; set; }
public string details_classifiction { get; set; }
}
You have to combine Enumerable.Where and Any.
List<BillWorkDetail>[] matchingSheetDetails = billSheetDetailList
.Where(sd => sd.billWorkDetails.Any(d => d.details_classifiction == "xyz"))
.Select(sd => sd.billWorkDetails)
.ToArray();
This creates an array of all matching lists. Since your question is unclear, if you actually only want an array of the matching BillWorkDetail objects:
BillWorkDetail[] matchingBillWorkDetails = billSheetDetailList
.SelectMany(sd => sd.billWorkDetails.Where(d => d.details_classifiction == "xyz"))
.ToArray();
SelectMany selects all matching BillWorkDetail out of the List<BillSheetDetail>. Note that both approaches lose the reference to the BillSheetDetail instance from where it came from.
The solution is using the Where clause:
mySheetDetail.billWorkDetails.Where(x => x.details_classification == "xyz").ToList();
Here is a demonstration of the code that is working well: http://ideone.com/s2cUaR
Try this linq method
List<BillWorkDetail> myBillWorkDetails = new Lis<BillWorkDetail>();
myBillWorkDetails = myBillSheetDetail.billWorkDetails.Where(b => b.classifiction == "xyz").ToList();
This code retrieve all BillWorkDetail with classification xyz.

Use IN operator in LINQ

I have List<Candidate> Candidates, List<Seat> Seats
The Model defined as shown below
public class Seat
{
public string CollegeId { get; set; }
public bool isFilled { get; set; }
public string SeatType { get; set; }
public string RollNumber { get; set; }
}
public class Candidate
{
public string RollNumber { get; set; }
public bool isAllotted { get; set; }
public string Quota { get; set; }
public int CandidateRank { get; set; }
public List<OptionPriority> SeatingPriorities { get; set; }
}
public class OptionPriority
{
public string CollegeId { get; set; }
public int PriorityRank { get; set; }
}
I need to filter List<Seat> from List<Seat> Seats where Seats.CollegeId IN List of CollegeID in SeatingPriorities.
// same as EXISTS
Seats.Where(s => SeatingPriorities.Any(sp => sp.CollegeId == s.CollegeId))
Also you can join seatings with seatings priorities:
// same as INNER JOIN
var prioritySeats = from s in Seats
join sp in SeatingPriorities
on s.CollegeId equals sp.CollegeId
select s;
NOTE: Both of queries above will not generate IN clause if you will execute them in LINQ to SQL or LINQ to Entities. IN is generated when you use Contains method of primitive types list:
var ids = SeatingPriorities.Select(sp => sp.CollegeId).ToList();
// same as IN
var prioritySeats = Seats.Where(s => ids.Contains(s.CollegeId));
var results = source.Where(x => SeatingPriorities.Contains(x.CollegeId)).ToList();
You can use Enumerable.Contains to find out the matches like you do with in
var result = lstSeats.Where(s=>SeatingPriorities.Contains(s.CollegeId));
Use Contains to achieve IN functionality in LINQ
You could use Any:
seats.Where(s => SeatingPriorities.Any(i => i.Id == s.CollegeId))
Since Contains only accepts an instance to compare (along with a possible IEqualityComparer<T>), which won't work if OptionPriority isn't an comparable to CollegeId (i.e. a string).

Categories

Resources