How do I Sort/OrderBy IList<Int32> - linq

I'm trying Sort on IList, I have tried different approach but none works
here is what my code looks like:
IList<IWebElement> listCountIdsUi = driver.FindElements(By.CssSelector("table#ct_ tr td:nth-of-type(1)"));
List<Int32> ui = new List<Int32>();
foreach (IWebElement option in listCountIdsUi)
{
if (!option.Text.ToString().StartsWith("Page"))
{
ui.Add(Convert.ToInt32(option.Text));
}
}
the only way I able to figured out is working with ArrayList
ArrayList al = new ArrayList(ui);
al.Sort();
is not possible using IList ?

OrderBy does NOT modify the underlying collection - it returns an IEnumerable that gives you the items in the order you ask for. So you have a few options:
Use List.Sort(), which does modify the underlying collection:
ui.Sort();
Store the sorted list in a new variable
var uiSorted = ui.OrderBy(s => s);
replace the existing reference
ui = ui.OrderBy(s => s).ToList();

Have you tried the List<T>.Sort method?
ui.Sort((a, b) => a.CompareTo(b));

var uiOrdered = ui.OrderBy(s => s).ToList() should be all you need to do.

Related

how to use a dynamic variable in orderby clause

am a newbie in linq.. am stuck with one scenario. ie,
i have to sort the search results based on user input.
user inputs are Last Name, First Name and Title. for input 3 drop downs are there and i have to sort result based on the values selected.
i tried
order = Request["orders"].Split(',');
var param = order[0];
var p1 = typeof(Test).GetProperty(param);
param = order[1];
var p2 = typeof(Test).GetProperty(param);
param = order[2];
var p3 = typeof(Test).GetProperty(param);
model.Test = (from tests in model.Test
select tests).
OrderBy(x => p1.GetValue(x, null)).
ThenBy(x => p2.GetValue(x, null)).
ThenBy(x => p3.GetValue(x, null));
but it doesn't works.
i want qry like this
from tests in model.Test
select tests).OrderBy(x => x.lastname).
ThenBy(x => x.firstname).ThenBy(x => x.Title);
order[0]== lastname but how can i use it in the place of OrderBy(x => x.order[0])..?
Thanks in advance.
i solved my case as follows
// list of columns to be used for sorting
List<string>order = Request["orders"].Split(',').ToList();
//map the column string to property
var mapp = new Dictionary<string, Func<Test, string>>
{
{"FirstName", x => x.FirstName},
{"LastName", x => x.LastName},
{"SimpleTitle", x => x.SimpleTitle}
};
//user inputted order
var paras = new List<Func<Test, string>>();
foreach (var para in order)
{
if(!string.IsNullOrEmpty(para))
paras.Add(mapp[para]);
}
//sorting
model.Test= model.Test.OrderBy(paras[0]).ThenBy(paras[1]).ThenBy(paras[2]);
Thanks all,
Actually you are looking for dynamic linq query than you can try out Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)
which allow to do like this
it means you can dynamically pass string propertyname to short you collection in orderby function
You can also read about : Dynamic query with Linq
You can compose the expression (any Expression) manually from pieces and then append it to the previous part of query. You can find more info, with example in "Sorting in IQueryable using string as column name".

LINQ Group By into a Dictionary Object

I am trying to use LINQ to create a Dictionary<string, List<CustomObject>> from a List<CustomObject>. I can get this to work using "var", but I don't want to use anonymous types. Here is what I have
var x = (from CustomObject o in ListOfCustomObjects
group o by o.PropertyName into t
select t.ToList());
I have also tried using Cast<>() from the LINQ library once I have x, but I get compile problems to the effect of it being an invalid cast.
Dictionary<string, List<CustomObject>> myDictionary = ListOfCustomObjects
.GroupBy(o => o.PropertyName)
.ToDictionary(g => g.Key, g => g.ToList());
I cannot comment on #Michael Blackburn, but I guess you got the downvote because the GroupBy is not necessary in this case.
Use it like:
var lookupOfCustomObjects = listOfCustomObjects.ToLookup(o=>o.PropertyName);
var listWithAllCustomObjectsWithPropertyName = lookupOfCustomObjects[propertyName]
Additionally, I've seen this perform way better than when using GroupBy().ToDictionary().
For #atari2600, this is what the answer would look like using ToLookup in lambda syntax:
var x = listOfCustomObjects
.GroupBy(o => o.PropertyName)
.ToLookup(customObject => customObject);
Basically, it takes the IGrouping and materializes it for you into a dictionary of lists, with the values of PropertyName as the key.
This might help you if you to Get a Count of words. if you want a key and a list of items just modify the code to have the value be group.ToList()
var s1 = "the best italian resturant enjoy the best pasta";
var D1Count = s1.ToLower().Split(' ').GroupBy(e => e).Select(group => new { key = group.Key, value = group.Count() }).ToDictionary(e => e.key, z => z.value);
//show the results
Console.WriteLine(D1Count["the"]);
foreach (var item in D1Count)
{
Console.WriteLine(item.Key +" "+ item.Value);
}
The following worked for me.
var temp = ctx.Set<DbTable>()
.GroupBy(g => new { g.id })
.ToDictionary(d => d.Key.id);

LINQ: Field is not a reference field

I've got a list of IQueryable. I'm trying to split this list into an array of IQueryable matching on a certain field (say fieldnum) in the first list...
for example, if fieldnum == 1, it should go into array[1]. I'm using Where() to filter based on this field, it looks something like this:
var allItems = FillListofMyObjects();
var Filtered = new List<IQueryable<myObject>(MAX+1);
for (var i = 1; i <= MAX; i++)
{
var sublist = allItems.Where(e => e.fieldnum == i);
if (sublist.Count() == 0) continue;
Filtered[i] = sublist;
}
however, I'm getting the error Field "t1.fieldnum" is not a reference field on the if line. stepping through the debugger shows the error actually occurs on the line before (the Where() method) but either way, I don't know what I'm doing wrong.
I'm farily new to LINQ so if I'm doing this all wrong please let me know, thanks!
Why don't you just use ToLookup?
var allItemsPerFieldNum = allItems.ToLookup(e => e.fieldnum);
Do you need to reevaluate the expression every time you get the values?
Why not use a dictionary?
var dictionary = allItems.ToDictionar(y => y.fieldnum);

Reproduce a "DELETE NOT IN" SQL Statement via LINQ/Subsonic

I want to do something like DELETE FROM TABLE WHERE ID NOT IN (1,2,3) AND PAGEID = 9
I have a List of IDS but that could be changed if needs be. I can't work out how to get a boolean result for the LINQ parser.
Here is what Subsonic expects I think.
db.Delete(content => content.PageID == ID).Execute();
I can't work out how to do the NOT IN statement. I've tried the List.Contains method but something not quite right.
UPDATE: One alternative is to do:
var items = TABLE.Find(x => x.PageID == ID)'
foreach(var item in items)
{
item.Delete();
}
This hits the database a lot more though
When you say "something not quite right" what exactly do you mean?
I'd expect to write:
List<int> excluded = new List<int> { 1, 2, 3 };
db.Delete(content => !excluded.Contains(content.PageID)).Execute();
Note that you need to call Contains on the array of excluded values, not on your candidate. In other words, instead of saying "item not in collection" you're saying "collection doesn't contain item."
Try .Contains:
db.Delete(content => content.PageID.Contains(<Array containing ID's>).Execute();
(the above is just an example, might need some polishing for your specific situation)
I have found that this works but its not via LINQ
var table = new WebPageContentTable(_db.DataProvider);
var g = new SubSonic.Query.Delete<WebPageContent(_db.DataProvider)
.From(table)
.Where(table.ID)
.NotIn(usedID)
.Execute();
I have found that this does work and via LINQ - however it hits the database multiple times.
var f = WebPageContent.Find(x => !usedID.Any(e => e == x.ID));
if (f.Count > 0)
{
var repo = WebPageContent.GetRepo();
repo.Delete(f);
}
This I imagine would work in one hit to the database but I get an exception thrown in QueryVisitor::VisitUnary
WebPageContent.Delete(x => !usedID.Any(e => e == x.ID));

How do I do a Client side sort of a DataTable using LINQ

How do I sort a DataTable on the client side using LINQ? (Server side sorting is not supported with my data store)
I was doing something like this which doesn't work
IEnumerable<DataRow> dr = GetDataTableData().AsEnumerable();
if (sortDirection == "Ascending")
{
dr = dr.OrderBy(x => sortExpression);
}
else
{
dr = dr.OrderByDescending(x => sortExpression);
}
GridView1.DataSource = dr;
GridView1.DataBind();
But I dont see the gridview sorting at all, what am I missing here?
My guess is that sortExpression is a string that you are passing in to the method; You should be sorting on something in x. eg:
dr = dr.OrderBy(x => x.FirstName);
As Rory pointed out in the comments, you can just use x[sortExpression] in your case; If you were using objects instead of the DataRow, you could make a key selector expression and pass it in to OrderBy() instead; something like:
Func<IDataRow, string> sortExpressionReal = x => x["FirstName"].ToString();
then your OrderBy would look like:
dr = dr.OrderBy(sortExpressionReal);
Do you have to use linq. You can do this quite easily with DataViews
DataView vw = new DataView(dtbl,"filter","FirstName DESC",DataViewRowState.CurrentRows);
GridView1.DataSource=vw;
GridView1.DataBind();

Resources