Split a list based on another list c# - c#

I have a list of strings like
List<string> mylist = new List<string> { "US", "UK" };
and another list variable contains the values like
List<string> countries = new List<string> { "US", "AU","NL" };
I just want to split the countries list into two based on my list
ex
list1 = { "US"};
list2 = { "AU","NL" };
I tried to group the list but i failed. any help?
var results = mylist.GroupBy(item => countries.Contains(item)).ToList();
var list1 = results.First().ToList();
var list2 = results.Last().ToList();
above code return the same mylist values for list1 and list2

You can use this;
var mylist = new List<string>{ "US", "UK" };
var countries = new List<string>{ "US", "AU","NL" };
var list1 = mylist.Intersect(countries).ToList();
var list2 = countries.Except(mylist).ToList();

Related

Return true if two lists contain any common values

I've two lists. I want to return a Boolean result true if both lists contain one or more common value(s), else return false.
List<String> list1 = new List<String> { "Alex", "James", "Donald", "Bill", "Trump" };
List<String> list2 = new List<String> { "Alex", "Tom", "Jerry", "Donald", "Gates", "Trump" };
I know list1.Intersect(list2) but obviously, it won't deliver true/ false output.
This can be achieved using Linq. As you already figured out .Intersect will yield a new list of items that are in both lists. All that is left is to check if anything is in that new list. An efficient solution can be done with .Any() which will return as soon as something is found.
list1.intersect(list2).Any()
See more about .Any() here: https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any?view=net-5.0
You can also do it using Any() and Where() like that:
List<String> list1 = new List<String> { "Alex", "James", "Donald", "Bill", "Trump" };
List<String> list2 = new List<String> { "Alex", "Tom", "Jerry", "Donald", "Gates", "Trump"};
var result = list1.Any(l1 => list2.Where(l2 => l2 == l1).Count() != 0);
And result here is "true"

All rows of a Datagridview to a IList<Object>

I have a datagridview with 4 columns that has numbers and string as values. How do I get all the data in a row and place it in a single IList. If it is not in a datagridview, this is how I would do it -
var formula1 = "=SUM(B3:B5)";
var formula2 = "=SUM(C3:C5)";
var formula3 = "=MAX(D3:D5)";
List<object> list1 = new List<object>() { "Item", "Cost", "Stocked", "Ship Date" };
List<object> list2 = new List<object>() { "Wheel", "20.50", "4", "3/1/2016" };
List<object> list3 = new List<object>() { "Door", "15", "2", "3/15/2016" };
List<object> list4 = new List<object>() { "Engine", "100", "1", "3/20/2016" };
List<object> list5 = new List<object>() { "Totals", formula1, formula2, formula3 };
IList<IList<Object>> list = new List<IList<Object>>() { list1, list2, list3, list4, list5 };
ValueRange VRange = new ValueRange();
VRange.Range = range;
VRange.Values = list;
But if it the values are in a datagridview, I don't know how to do it anymore. Can you please teach a noob. Thank you.
You can use linq to create a List<List<object>> from your DataGridView this way:
var list = dgv.Rows.Cast<DataGridViewRow>().Where(r => !r.IsNewRow)
.Select(r => r.Cells.Cast<DataGridViewCell>().Select(c => c.Value).ToList())
.ToList();
Thanks for your time. I got it like this...
IList<IList<Object>> list = new List<IList<Object>>() { };
for (var i = 0; i < dgvAttendance.Rows.Count - 1; i++)
{
List<object> lists = new List<object>() { dgvAttendance.Rows[i].Cells[0].Value.ToString(),
dgvAttendance.Rows[i].Cells[1].Value.ToString(), dgvAttendance.Rows[i].Cells[2].Value.ToString(),
dgvAttendance.Rows[i].Cells[3].Value.ToString() };
list.Add(lists);
}
ValueRange VRange = new ValueRange();
VRange.Range = range;
VRange.Values = list;

Order List Object in same order as another list in C#

I have a List object as following:
var list1 = new List<DummyObject> {
new DummyObject { ID="1", UniqueCode="ltrasd8ShFwNEyWrPTd9jIJJQ" },
new DummyObject { ID="2", UniqueCode="GB456rpcpxRYEeOr32w5oRMwg" },
new DummyObject { ID="3", UniqueCode="Y7twLumNJU6dQZLR0KxqA" },
new DummyObject { ID="4", UniqueCode="nG3vejzzxkiO21oDt58vkw" },
new DummyObject { ID="5", UniqueCode="aPwwG1JMYUGTvOL2lG0YFg" },
}
and another List object definition with Ids is:
List<int> list2 = new List<int>() { 2, 4, 5, 1, 3 };
I want to order the list1 by the list2 and the result should be as following:
var output= new List<DummyObject> {
new DummyObject { ID="2", UniqueCode="ltrasd8ShFwNEyWrPTd9jIJJQ" },
new DummyObject { ID="4", UniqueCode="GB456rpcpxRYEeOr32w5oRMwg" },
new DummyObject { ID="5", UniqueCode="Y7twLumNJU6dQZLR0KxqA" },
new DummyObject { ID="1", UniqueCode="nG3vejzzxkiO21oDt58vkw" },
new DummyObject { ID="3", UniqueCode="aPwwG1JMYUGTvOL2lG0YFg" },
}
Can anyone please guide me here how to acheive this using LINQ?
If the lists are small, then you can do it like this:
var result = list1.OrderBy(x => list2.IndexOf(Convert.ToInt32(x.ID))).ToList();
If the lists are large, then the following solution will perform better:
//Create a dictionary that maps the integer values of the IDs to the objects
var dictionary = list1.ToDictionary(x => Convert.ToInt32(x.ID), x => x);
var result = list2.Select(x => dictionary[x]).ToList();
You can do this with LINQ like this:
var output = list1.OrderBy(dummyObject => list2.IndexOf(int.Parse(dummyObject.ID))).ToList();
Join preserves the order of the elements of outer sequence (list2), and for each of its elements, the order of the matching elements of inner sequence (list1)
var output = list2.Join(list1, i => i.ToString(), o => o.ID, (i,o) => o)
.ToList();
try this
var _orderedList = (from l2 in list2 join l1 in list1 on l2 equals int.Parse(l1.ID) select l1).ToList();

How can I add list parameters to a LINQ query?

I have two parameters passed to the method and I need to attach them to the final query list.
(1st parameter)
string[] Price= new string[5];
Price= new string[] { "50", "25", "35" };
(2nd parameter)
List<string> DiscountPrice= new List<string>();
DiscountPrice.Add ("10");
DiscountPrice.Add ("5");
DiscountPrice.Add ("3");
var list= (from d in context.List
where ....
select new MyNewList
{
Name = d.Name,
Country = d.Country,
**Price = ??** //how do I attach the parameters one by one? In the order they were saved?
**DiscountPrice** = ??
}).ToList<MyNewList>();
It sounds like you want to match list elements by index. You can iterate from zero to the number of list elements and access each element by its index:
var prices = new string[] { "50", "25", "35" };
var discountPrices = new List<string>() { "10", "5", "3" };
var items = (from d in context.List
where ....
select new { d.Name, d.Country }).ToList();
var list = (from index in Enumerable.Range(0, items.Count())
select new MyNewList
{
Name = items[index].Name,
Country = items[index].Country,
Price = prices[index],
DiscountPrice = discountPrices[index]
}).ToList();
Another way is to Zip everything together:
var list = items.Zip(prices, (item, price) => new { item, price })
.Zip(discountPrices, (x, discountPrice) => new { x.item, x.price, discountPrice})
.Select(x => new MyNewList
{
Name = x.item.Name,
Country = x.item.Country,
Price = x.price,
DiscountPrice = x.discountPrice
})
.ToList();

Convert nested type in C# using delegates / LINQ

How can I convert a List<List<string>> to a List<string[]> in C# in a concise way using delegates/LINQ?
I believe this will do it:
var result = (from list in listOfLists select list.ToArray()).ToList()
var lists = new List<List<string>>();
List<string[]> arrays = lists.ConvertAll(l => l.ToArray());
List<List<string>> listOfLists = new List<List<string>>();
listOfLists.Add(new List<string>(){ "bla", "foo", "bar"});
listOfLists.Add(new List<string>() { "alfa", "beta", "gama" });
listOfLists.Add(new List<string>() { "earth", "moon", "sun" });
listOfLists.Add(new List<string>() { "cat", "dog", "owl" });
List<string[]> listOfArrays = new List<string[]>();
listOfArrays = listOfLists.Select(l => l.ToArray()).ToList();

Categories