List<string> testList = new List<string>();
testList.Add("A");
testList.Add("A");
testList.Add("C");
testList.Add("d");
testList.Add("D");
This query is case sensitive:
// Result: "A"
List<String> duplicates = testList.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToList();
How would it look case insensitive? (Result: "A", "d")
By using overloaded implementation of the GroupBy where you can provide the comparer required, e.g. StringComparer.OrdinalIgnoreCase:
var result = testList
.GroupBy(item => item, StringComparer.OrdinalIgnoreCase)
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToList();
By replacing
.GroupBy(x => x)
with
.GroupBy(x => x.ToLower())
you turn all string elements to lower case and group case insensitive.
var result = testList.GroupBy(x => x.ToLower())
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToList();
Related
I have this datatable (RadkyData):
Name EAN PRICE
ITEM1 12345 10
ITEM2 5558 55
ITEM3 12345 44
I need to search rows with duplicate value EAN.? (a list of all EAN that are duplicate)
I have this code:
var polozkySum = RadkyData.AsEnumerable()
.Select(r => new
{
c2 = r.Field<string>("EAN")
})
.GroupBy(g => new { g.c2 })
.Select(x => new
{
col2 = x.Key.c2
});
Have you any ideas please?
var rowsWithDupEAN = RadkyData.AsEnumerable()
.GroupBy(row => row.Field<string>("EAN"))
.Where(g => g.Count() > 1)
.SelectMany(g => g);
If you don't want the rows but only this column values(as mentioned in a comment):
var dupEanList = RadkyData.AsEnumerable()
.GroupBy(row => row.Field<string>("EAN"))
.Where(g => g.Count() > 1)
.Select(g => g.Key)
.ToList();
You can use LINQ to DataTable.
var result = Radkydata.AsEnumerable()
.GroupBy(r => r.Field<string>("EAN"))
.Select(g => g.First())
.CopyToDataTable();
I'm using this query to count number of orders by date. I'm trying to add one more parameter that counts total products for each order, however I can't get it to work atm.
This is the essential part of a method that is suposed to return a list of 3 parameters (Date, TotalOrders and TotalProducts). Im using a Linq query to get a list with total order for each date, im wondering how to add my third parameter to the list "TotalProducts" and if i can do by adding one more search parameter in the Query. The foreach part below do not work propertly, it will return a list of TotalProducts but CreationDate will be the same for ech item in the list. I also have a feeling putting a foreach inside a foreach dosn't seem optimal for this:
var orders = _orderService.SearchOrderStatistics(startDateValue, endDateValue, orderStatus,
paymentStatus, shippingStatus, model.CustomerEmail, model.OrderGuid);
var result = orders.Where(o => o.PaymentStatus == PaymentStatus.Paid)
.GroupBy(g => g.CreatedOnUtc.Date.ToString("yyyyMMdd"))
.Select(s => new { Date = s.Key, Count = s.Count() });
List<GCOrdersModel> TotalOrdersPaid = new List<GCOrdersModel>();
foreach (var g in result)
{
foreach (var opv in orders)
{
GCOrdersModel _Om = new GCOrdersModel(g.Date, g.Count.ToString(), opv.OrderProductVariants.Count.ToString());
TotalOrdersPaid.Add(_Om);
}
}
return TotalOrdersPaid;
To access total products for every orders I must use OrderProductVariants.Count.ToString()
Can I add this parameter to the query?
Thx
You could try this:
return orders.Where(o => o.PaymentStatus == PaymentStatus.Paid)
.GroupBy(g => g.CreatedOnUtc.Date.ToString("yyyyMMdd"))
.Select(s => new GCOrdersModel()
{
Date = s.Key,
Count = s.Count(),
OpvCount = opv.OrderProductVariants.Count.ToString()
})
.ToList();
or
return orders.Where(o => o.PaymentStatus == PaymentStatus.Paid)
.GroupBy(g => g.CreatedOnUtc.Date.ToString("yyyyMMdd"))
.Select(s => new GCOrdersModel(s.Key, s.Count, opv.OrderProductVariants.Count.ToString()))
.ToList();
That way, you don't have to iterate over your result again. And it automatically creates your list of GCOrdersModel.
Edit
Does this work?
return orders.Where(o => o.PaymentStatus == PaymentStatus.Paid)
.GroupBy(g => g.CreatedOnUtc.Date.ToString("yyyyMMdd"))
.Select(s => new GCOrdersModel()
{
Date = s.Key,
Count = s.Count(),
OpvCount = s.OrderProductVariants.Count.ToString()
})
.ToList();
or
return orders.Where(o => o.PaymentStatus == PaymentStatus.Paid)
.GroupBy(g => g.CreatedOnUtc.Date.ToString("yyyyMMdd"))
.Select(s => new GCOrdersModel(s.Key, s.Count(), s.OrderProductVariants.Count.ToString()))
.ToList();
How about:
var opvCount =
opv
.OrderProductVariants
.Count
.ToString();
return
orders
.Where(o => o.PaymentStatus == PaymentStatus.Paid)
.GroupBy(g => g.CreatedOnUtc.Date.ToString("yyyyMMdd"))
.Select(s => new
{
Date = s.Key,
Count = s.Count()
})
.Select(x =>
new GCOrdersModelg(x.Date, g.Count.ToString(), opvCount));
I use the following code to extract words from string input, how can I get the occurrence of each words too?
var words = Regex.Split(input, #"\W+")
.AsEnumerable()
.GroupBy(w => w)
.Where(g => g.Count() > 10)
.Select(g => g.Key);
Instead of Regex.Split you can use string.Split and get the count for each word like:
string str = "Some string with Some string repeated";
var result = str.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)
.GroupBy(r => r)
.Select(grp => new
{
Word = grp.Key,
Count = grp.Count()
});
If you want to filter out those words which are repeated 10 times atleast then you can add a condition before Select like Where(grp=> grp.Count >= 10)
For output:
foreach (var item in result)
{
Console.WriteLine("Word: {0}, Count:{1}", item.Word, item.Count);
}
Output:
Word: Some, Count:2
Word: string, Count:2
Word: with, Count:1
Word: repeated, Count:1
For case insensitive grouping you can replace the current GroupBy with:
.GroupBy(r => r, StringComparer.InvariantCultureIgnoreCase)
So your query would be:
var result = str.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)
.GroupBy(r => r, StringComparer.InvariantCultureIgnoreCase)
.Where(grp => grp.Count() >= 10)
.Select(grp => new
{
Word = grp.Key,
Count = grp.Count()
});
Try this:
var words = Regex.Split(input, #"\W+")
.AsEnumerable()
.GroupBy(w => w)
.Select(g => new {key = g.Key, count = g.Count()});
Remove the Select statement to keep the IGrouping which you can use to view both the keys and take a count of values.
var words = Regex.Split(input, #"\W+")
.AsEnumerable()
.GroupBy(w => w)
.Where(g => g.Count() > 10);
foreach (var wordGrouping in words)
{
var word = wordGrouping.Key;
var count = wordGrouping.Count();
}
You could produce a dictionary like this:
var words = Regex.Split(input, #"\W+")
.GroupBy(w => w)
.Select(g => g.Count() > 10)
.ToDictionary(g => g.Key, g => g.Count());
Or if you'd like to avoid having to compute the count twice, like this:
var words = Regex.Split(input, #"\W+")
.GroupBy(w => w)
.Select(g => new { g.Key, Count = g.Count() })
.Where(g => g.Count > 10)
.ToDictionary(g => g.Key, g => g.Count);
And now you can get the count of words like this (assuming the word "foo" appears more than 10 times in input):
var fooCount = words["foo"];
Here is what I am doing in my LINQ on a datatable.
var result = resTable.Rows.Where(r => Map.ContainsKey(string.Concat(r[HeaderCol].ToString().Trim(),dot,r[FooterCol].ToString().Trim(),dot,r[TypeCol].ToString().Trim())))
.GroupBy(r => string.Concat(r[HeaderCol].ToString().Trim(), dot, r[FooterCol].ToString().Trim(), dot, r[TypeCol].ToString().Trim()))
.ToDictionary(g => g.Key,
g => g.GroupBy(r => DateTime.FromOADate((double)r[DateCol]))
.ToDictionary(c => c.Key,
c => c.Select(r => new ResultObj(DateTime.FromOADate((double)r[ResultDateCol]), new Decimal((double)r[PriceCol])))
.ToList()));
I am creating a key from column values and need to use it in group by as well.
string.Concat(r[HeaderCol].ToString().Trim(), dot, r[FooterCol].ToString().Trim(), dot, r[TypeCol].ToString().Trim())
Any way I can do string concat only once and use it twice in LINQ ?
I don't know why it is necessary, but here t you want.
var result = resTable.Rows.Select(r => new {r, res = string.Concat(r[HeaderCol].ToString().Trim(),dot,r[FooterCol].ToString().Trim(),dot,r[TypeCol].ToString().Trim())})
.Where(r => Map.ContainsKey(r.res))
.GroupBy(r => r.res)
.ToDictionary(g => g.Key,
g => g.GroupBy(r => DateTime.FromOADate((double)r.r[DateCol]))
.ToDictionary(c => c.Key,
c => c.Select(r => new ResultObj(DateTime.FromOADate((double)r.r[ResultDateCol]), new Decimal((double)r.r[PriceCol])))
.ToList()));
I have the following:
var topRole = 25;
var menuItems = _contentRepository.GetPk()
.Where(m => m.Status <= topRole)
.OrderBy(m => m.Order)
.Select(m => new MenuItem
Status has values of "00", "05" or "10"
Is there some way I can convert m.Status to an integer and then compare to see if it is less than or equal to topRole?
var menuItems = _contentRepository.GetPk()
.Where(m => int.Parse(m.Status) <= topRole)
.OrderBy(m => m.Order)
.Select(m => new MenuItem);
If this query is for LINQ to SQL, you may need to use Convert.ToInt32 instead:
var menuItems = _contentRepository.GetPk()
.Where(m => Convert.ToInt32(m.Status) <= topRole)
.OrderBy(m => m.Order)
.Select(m => new MenuItem);
use int.Parse(m.Status)
var menuItems = _contentRepository.GetPk()
.Where(m => int.Parse(m.Status) <= topRole)
.OrderBy(m => m.Order)
.Select(m => new MenuItem)
EDIT: changed "parse" to "Parse".