How to Compare two properties and then sort [duplicate] - c#

This question already has answers here:
List<string> complex sorting
(5 answers)
Closed 6 years ago.
I have a list of strings in order I've set manually "1" "2" "5" "4" "3" etc.. I also have another class tied to a number of elements which contains various properties, one of which is an int OrderString
How do I re-arrange the order of the objects according to my list of strings.
list<string> L_string = new string { "1" "2" "4" "3" "5" "6" "7"}
Also a list of Items the that properties such as Name, Number, Date attached to them.
Assuming l_Item inherits from Products
var SortedMan =
l_Item.OrderBy(o=>o.number.ToString()).CompareTo(L_string)));
Something like that, but an actual working code.
So basically the amount of items in both will be the same. I need it to re arrange list of Items in order of how they are inside the L_string.

You can use this GenericComparer class implementation.
Use somehting like this
Array.Sort(YourArray, new GenericComparer());
Or use
Array.Sort(YourArray, new PropertyDescriptorComparer());
for property of class.

Assuming I_Item is a List<Product>:
var sortedList = new List<Product>();
foreach (var value in L_string)
{
sortedList.AddRange(I_Item.Where(x => x.number.ToString() == value));
}

Assuming that entries in L_string actually correspond to items in l_item, you can do something like this:
var sorted = l_item
.Where(item => L_string.Contains(item.number.ToString()))
.OrderBy(item => L_string.IndexOf(item.number.ToString()));
The Where method filters the collection and returns a new collection with all matching elements. OrderBy reorders the collection based on the item's index in the L_string collection.

Related

How can I pair up two items from a list using linq?

I have a list that looks like this:
List<string> list = new List<string>()
{
"item1",
"item2",
"item3",
"item4"
};
I want to group the items in a way that I have them paired up like this:
[("item1", "item2"),("item3", "item4")]
I dont mind what type I have on return, if its a List, an IGrouping, an array, IEnumerable<Tuple>.. I just want them paired up. I've already achieved this with a simple for messing with the indices but I'm wondering if I can do it with linq (what is my actual object of study here)
In .NET 6, you can use LINQ Chunk<TSource>(int size).
IEnumerable<string[]> groups = list.Chunk(2);

how to sort String list with multiple objects by descending order

Ive got a list which contains data separated by a comma.
Its part of a C# ASP.net project.
so the data in my list looks like this:
10323323,102,99-11
13223,101,00-10
23234323223,178,00-99
I want to re-arrange the list so that the value in the middle arranges the items in the lost in descending order so id end up with a list that looks like.
13223,101,00-10
10323323,102,99-11
23234323223,178,00-99
If your strings are always 3 values comma-separated, and the middle value is a string representation of an integer, something like this should do the job:
List<string> list = new List<string>()
{
"10323323,102,99-11",
"13223,101,00-10",
"23234323223,178,00-99"
};
list = list.OrderBy(x => Convert.ToInt32(x.Split(',')[1])).ToList();

Splitting an ordered list [duplicate]

This question already has answers here:
Group by in LINQ
(11 answers)
Closed 4 years ago.
I am trying to create a sorted list of lists. Where the outer "layer" is sorted by the field BU. and the inner layer is sorted by JobNum. I have this method, and variables.
public List<string> ListSorter<T>(IEnumerable<T> records)where T :
IMapToCSVSource, new()
List<IEnumerable<T>> organizedRecords = new List<IEnumerable<T>>();
List<T> shortenedRecord = new List<T>();
Here I am trying to create a more concise object with only 3 specific fields instead of the possible 8 that comes with the records object. BU and JobNum are set within this method.
foreach (var record in records)
{
string businessUnit = "research"; //This would vary each loop, not constant as displayed
string JobNum = "test" //this would vary each loop, not constant as displayed
shortenedRecord.Add(new T()
{
Cost = record.Cost,
BU = businessUnit,
JobNum = jobNum
});
}
shortenedRecord.OrderBy(o => o.BU).ThenBy(n=>n.JobNum);
here, to my knowledge, now has all the records shortened and ordered by BU, then JobNum.
Now I want to Split this ordered list into sections of BU specific records and add it to organizedRecords. Such that each element of organizedRecords is a specific BU. How would I do this?
For example, say shortenedRecord is a list of 30 elements, but there is only a total of 5 unique BU values. I would like to order and SPLIT the list into their 5 respective BU values, and add it to organizedRecords.
such that:
organizedRecords[0] should be a list of 'corporate' records
organizedRecords[1] should be a list of 'research' records
where corporate and research are BU values.
I tried to explain as best I could. Thank you for any suggestions.
Thanks for suggestions, I toyed around a bit, and I found this to work as I needed it.
var query = shortenedRecord.GroupBy(p => p.BU).ToList();
foreach (var group in query)
{
var ordered = group.OrderBy(x => x.JobNum);
organizedRecords.Add(ordered);
}

Filter list to remove non numeric items

I am using the following controller method to grab the id's of all selected items in my Grid.Mvc, however I am noticing I am getting not only the id's of the selected items, but also a "false" for each row, which obviously I don't want.
I have put together the following code smell to leave me with just the id's so that I can do my thing however is there a better way of doing this, at the very least is there a way of filtering out the non numeric list items rather than my existing method which is hardcoding true/false:
//POST
[HttpPost]
[ActionName("Index")]
public ActionResult IndexPost(FormCollection collection)
{
var selectedIds = collection.GetValues("selectedAddressesIds");
List<string> myList = new List<string>();
myList = selectedIds.ToList();
myList.RemoveAll(x => (x == "false") || (x == "true"));
if (myList != null )
{
foreach (var id in myList)
{
// do what you want with the selected id.
}
}
return View();
}
To answer just the question about filtering, you could retrieve just the numeric values using one of these options:
var exampleList = new List<string>{"1", "2", "rubbish", "3", "trash", "4.5"};
int dummyInt; // just because you need an out param of type int
// filteredInts will contain {1, 2, 3}
var filteredInts = exampleList.Where(item => int.TryParse(item, out dummyInt));
double dummyDouble; // just because you need an out param of type double
// filteredDoubles will contain {1, 2, 3, 4.5}
var filterdDoubles = exampleList.Where(item => double.TryParse(item, out dummyDouble));
Ofcourse, if you just want to filter the original list, you can use the complementary logic for RemoveAll():
// If you only want int values:
myList.RemoveAll(item => ! int.TryParse(item, out dummyDouble));
// ..or want to also keep double values:
myList.RemoveAll(item => ! double.TryParse(item, out dummyDouble));
If the GetValues("selectedAddressesIds") method is returning things other than the IDs of the selected addresses, that is the problem that you should fix rather than tweaking the results list.
Without seeing where the results come from I'm not sure why you have values of "true" and "false" in this list, but if it is for every entry then it shouldn't be too hard to find if you look at where the selectedAddressesIds collection is populated.
To answer the title question more directly, though, if you merely want to avoid hard-coding "true" and "false" you can try to parse to int and discard any that don't parse:
List<string> myList = new List<string>();
int dummy; // because TryParse takes an out parameter
myList.RemoveAll(x => !int.TryParse(x, out dummy));
But, I'd encourage you to find the root cause of the invalid values.

Compare to list<String> using linq?

I have 3 list List
ListMaster contains {1,2,3,4,....} ..getting populated from DB
List1 contains {1,3,4}
List2 contains {1,3,95}
how to check Which list items are present in master list using linq
var inMaster = List1.Intersect(ListMaster);
or for both list :
var inMaster = List1.Intersect(List2).Intersect(ListMaster);
check if any item from list1, list2 exist in master
var existInMaster = inMaster.Any();
You can use Enumerable.Intersect:
var inMaster = ListMaster.Intersect(List1.Concat(List2));
If you want to know which are in List1 which are not in the master-list, use Except:
var newInList1 = List1.Except(ListMaster);
and for List2:
var newInList2 = List2.Except(ListMaster);
Can i use a list .all to check all item of a list in another list for
list of string
So you want to know if all items of one list are in another list. Then using Except + Any is much more efficient(if the lists are large) because Intersect and Except are using sets internally whereas All loops all elements.
So for example, does the master-list contain all strings of List1 and List2?
bool allInMaster = !List1.Concat(List2).Except(ListMaster).Any();
You can use Enumerable.Intersect method like;
Produces the set intersection of two sequences by using the default
equality comparer to compare values.
var inMaster1 = List1.Intersect(ListMaster);
var inMaster2 = List2.Intersect(ListMaster);
Here is a DEMO.

Categories