Get unique items from multiple lists using LINQ- C# [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have 3 lists.
ListA<items>
ListB<items>
ListC<items>
I have to select one item from each list but the item.itemID should be unique for each of those items. How can i achieve this? Thanks in advance.

List<items> concat = new List<items>();
concat.AddRange(ListA);
concat.AddRange(ListB);
concat.AddRange(ListC);
List<items> result = new List<items>();
foreach (var item in concat)
{
if (result.Where(x => x.itemId == item.itemId).Count() == 0)
{
result.add(item);
}
}
//result should now contain what you are looking for

So you want exactly one item from each list, where that item hasn't been selected already from a previous list?
Then select from the lists where the ID isn't in the previous selection. Maybe something like this:
var itemA = listA.First(); // any item is unique, since this is our first one
var itemB = listB.First(b => b.ID != itemA.ID);
var itemC = listC.First(c => c.ID != itemA.ID && c.ID != itemB.ID);
If the count of lists isn't known then we'd need to make this a little more dynamic. Maybe something like this:
var selectedItems = new List<Item>();
foreach (var list in listOfLists)
selectedItems.Add(list.First(x => selectedItems.Count(y => y.ID == x.ID) == 0));
What this does is loop through the "list of lists" (since the number of lists isn't known, it must be in a collection data structure) and get the first item from each one where the currently known selected items do not have a matching ID. This should result in one selected item from each list.
(This all assumes that the lists contain a valid item that you're looking for. If that's not the case, you might use FirstOrDefault() instead and check for nulls.)

public class items
{
public int id {get;set;}
}
void Main()
{
var l1=new List<items>{new items {id=1}, new items {id=2}, new items {id=3}};
var l2=new List<items>{new items {id=2}, new items {id=3}, new items {id=4}};
var l3=new List<items>{new items {id=1}, new items {id=2}};
var result=l1
.Join(l2,(k1)=>true,(k2)=>true,(a1,a2)=>new {a1,a2})
.Join(l3,(k1)=>true,(k2)=>true,(b1,b2)=>new {b1.a1,b1.a2,a3=b2})
.Where(rec=>rec.a1.id!=rec.a2.id && rec.a2.id!=rec.a3.id && rec.a1.id!=rec.a3.id)
.First();
Console.WriteLine("{0},{1},{2}",result.a1.id,result.a2.id,result.a3.id);
}
Of the possible answers (132,142,231,241,321,341,342) it will pick and return the first one (132).
Example code: http://csharppad.com/gist/98a076bdd4e01dbd82be

Related

Updating fields in one list from another list [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Is there a better or more efficient way to do this?
Both of these objects have the same Id and some similar fields that I want to update.
foreach (var i in oldItems)
{
foreach (var j in newItemValues)
{
if(i.id == j.Id)
{
j.field1 = (decimal)i.field1;
j.field2 = (decimal)i.field2;
}
}
}
try this maybe you are like this;
foreach (var n in newItemValues)
{
Item item = oldItems.FirstOrDefault(x => x.Id == n.Id);
if (item != null)
{
n.field1 = item.field1;
n.field2 = item.field2;
}
}
Edit: If you keep oldItems in a HashSet or HashTable by keeping key as Id the time taken will slow to O(N).
Convert oldItems or newItemValues into a Map before looping.
That will reduce computational complexity from O(n^2) to O(n)
You can do this by Linq Query
newItemsValues =
(from t1 in oldItems
join t2 in newItemsValues on t1.Id equals t2.Id
select new YourModel { field1 = t1.field1 ,field2 = t1.field2 }
).ToList();
result will a list of all matching items where oldItems Id will be equals to newItemsValues Id

Group by custom list linq c# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have problem in understanding custom group by and order by. Here is the scenario,
I have an object contain data.
Objects->object->name; (structure of the object)
and i want to group by custom list that i have (name is the key object for grouping).
name is like a,b,c and i want b,c,a(sample).
Here is my work around
IOrderedEnumerable<IGrouping<string, Snit>> assetGrouping = sUnits.ToArray().GroupBy(e => e.Name).OrderBy(e => e.Key);
and i want to group and order by my custom list
List<string > customOrder=new List<string>();
customOrder.Add("any");
customOrder.Add("some");
can any body help me..
This is what I scrapped using LINQPad:
Prerequisites:
public class Data
{
public string Name {get; set;}
}
var keys = new[]{"1", "15", "13", "16"};
var random = new Random();
var data = Enumerable.Range(1, 100)
.Select( _ => new Data
{
Name = random.Next(24).ToString()
});
var keys = new[]{"1", "15", "13", "16"};
Now, the grouping:
var grouped = data.GroupBy(x => keys.FirstOrDefault(k=>k==x.Name));
The query above will group the items in data as following: for each value x in data, if there is a key k in keys with k == x.Name, the value will be added to a separate group having the key k; all the other values will be added to a separate group having the key null;
For the ordering of the groups you just need to use the position of each group key in the keys array.
var ordered = grouped.OrderBy( g =>
{
var index = Array.IndexOf(keys, g.Key);
return index == -1 ? int.MaxValue : index;
});
Array.IndexOf will return -1 if the item wasn't found in the dictionary. In this case, according to your needs, the item must be at the end of the collection so return max value. Otherwise, just use the index of the key.
The results are in the image below:

Linq AND for each item in list

I have a List of ints. I need to select elements from a data source where a particular field/column matches each int in the list.
Data Source Example
ItemID ListID
1 1
1 2
2 1
I want to find all Items that match all ListIDs from a List containing List IDs 1 and 2.
Currently I'm using...
List<Item> items = (from element in MyItems where listIDs.Contains(element.ListID) select element).ToList();
However, this produces an OR query and not an AND query across multiple rows for each distinct ItemID.
You can try this way :
List<Item> result = MyItems.GroupBy(o => o.ItemID)
//find group that contain all listIDs
.Where(o => !listIDs.Except(o.Select(x => x.ListID)).Any())
//flatten groups to items
.SelectMany(o => o)
.ToList();
Related question : Determine if a sequence contains all elements of another sequence using Linq
If you are trying to compare two list for equality, then you could use SequenceEqual method.
Something along the lines
list<item> results = (from element in MyItems where listIDs.SequenceEqauls(element.ListID) select element).ToList();
I am not entirely sure if I understood your question properly. When you say "particular field/column," is that field/column some kind of collection as well?
if i got your question !! then try this
var MyItems=<your data column values>
var ItemsMatch=MyItems.Where(z=>MyIntsList.Contains(int.Pars(z.ToString()))).ToArray();
I'm not sure I understand the question. I think you have a list and you are trying to match rows that have both ListID & ItemID equal to ANY item in the list. If thats what you are sking this this is a way to do it:
List<Item> items = from element in MyItems
where listIDs.Contains(element.ListID) and listIDs.Contains(element.ItemID)
Or perhaps you are trying to match rows that have both ListID & ItemID equal to the SAME item in the list. If thats what you are sking this this is a way to do it:
List<Item> items = from element in MyItems
where listIDs.Contains(element.ListID) and element.ListID == element.ItemID
If i understood you correctly,this will do:
var result = (from item in MyItems
from i in listIDs
where i == item.ListId
select item).ToList();
It will get all Item objects in MyItems list that have ListId present in ListId.

List<object> compare [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I have searched for a few examples and not found one that is similar to what I have and what I want to achieve.
I have 2 lists
class object1
{
string obj1_name;
int obj1_qty;
}
List<object1> listA
class object2
{
string obj2_name;
int obj2_qty;
}
List<object2> listB;
Now, using ListA as the primary list I want to see if ListB contains an object with the same name and if so, what is the quantity and hence, does the obj1_qty = obj2_qty each other? if not, there is a difference and I need to show it, most likely in a 3rd list which would be the difference, of the qty's if they exist. Note, ListA can be bigger or smaller than ListB
Show All List A (master list contains all objects)
Show the difference between those names/qty's that exist in both lists.
Gracias
Souncs like a join would work for you:
var query = from a in listA
join b in listB on a.obj1_name equals b.obj2_name
where a.obj1_qty != b.obj2_qty
select new {
Name = a.obj1_name,
QtyA = a.obj1_qty,
QtyB = b.obj2_qty,
Diff = a.obj1_qty - b.obj2_qty
};
The simpelest way to do this is just use a join from Linq
var items = from l1 in listA
join l2tmp1 in listB on l1.obj1_name equals l2.obj2_name into l2tmp2
from l2 in l2tmp2.DefaultIfEmpty();
select new {
ItemA = l1,
ItemB = l2,
Name = l1.obj1_name,
Difference = (l2 == null) ? 0 : l1.ob1_qty - l2.ob2_qty
};
items will now hold a IEnumerable of a anonymous class that holds the a reference to the item in ListA, a reference to the item in listB, the matching name, and the difference.

Working with List [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have two list : (Note: List's Items are combination of "NAME" & "ID" )
List<string> ListA = new List() {"SAM001","SAM002","SAM003","PIT001","PIT002","PIT004","ROSE001","ROSE002","JASE001" };
//so on
List<string> ListB = new List() {"SAM001","SAM003","PIT000","ROSE002","JASE001","INDI000"};`
//so on...
Now Based on these two list i want to create two new list suppose listCommon & listUncommon.
listCommon will contain all matched items of ListA & ListB.
listUnCommon will contain all remaining items of ListA
Now My condition is if Any item in ListB has NAME + 000 then all the items of ListA starting with that Name should add in my listCommon.
Example 1 : if ListB item is PIT000 and ListA item are PIT001,PIT002,PIT003,ABC001
then listCommon = PIT001,PIT002,PIT003 because ListB has PIT with 000 so condition true all ListA 'PIT' items added in listcommon
So as above list and my condition i want my final list below
List<string> listCommon = new List() {"SAM001","SAM003", "PIT001","PIT002","PIT004","ROSE002", "JASE001" };
List<string> listUncommon = new List() {"SAM002", "ROSE001"};
Please suggest..i just spend my couple of minutes in loops but not getting actual result as i mentioned :(
This should work.
var common = ListA.Intersect(ListB)
.Concat(
ListA.Where(a =>
ListB.Any(
b => b.EndsWith("000") &&
b.StartsWith(a.Substring(0, a.Length - 3))
)
)
);
var uncommon = ListA.Except(common);
Using an insersect, then you are selecting any from list A where list B has an entry that matches the first 3 letters and ends with 000.
This is not the most efficient way of doing this, however it is terse code-wise.
Finding the common items from 2 lists:
var listCommon = list1.Intersect(list2);
Updated - Subtracted items:
var subtractedItems = new HashSet(listCommon);
commonItems.ExceptWith(list1);

Categories

Resources