Reputation: 829
I have settings class
public class Setting
{
public virtual string Key { get; set; }
public virtual string Value { get; set; }
}
and i have to list
IEnumerable<Setting> A1 => contain {"A","1"}{"B","2"}
IEnumerable<Setting> A2 => contain {"A","1"}{"B","5"}
i want linq statment to chose the element from list A2 that have same key and different value here is {"B","5"}
I have try
A2.Where(x => A1.Any(y => y.Value != x.Value)).ToList();
this give me the two elemnts in A2
can any one help me thank you
**Edit ** my settings class
public class Setting : Entity<int>
{
public virtual DateTime? ModificationDate { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual string Key { get; set; }
public virtual string Value { get; set; }
public virtual string ModifiedBy { get; set; }
public virtual string Type { get; set; }
public virtual string ValidateRegex { get; set; }
public virtual bool IsSystem { get; set; }
}
and i have return from mvc IEnumerable<Setting>
let it name settings,
then i get from database the original settings IEnumerable<Setting>
let it name dbsettings
i want to know the changed value from settings to make update on it
Upvotes: 2
Views: 5480
Reputation: 22456
You need to compare the Key
as well:
A2.Where(x => A1.Any(y => y.Key == x.Key && y.Value != x.Value)).ToList();
The following sample returns { "B", "5" }
as the result:
void Main()
{
var a1 = new List<Setting>(new Setting[] {
new Setting() { Key = "A", Value = "1" },
new Setting() { Key = "B", Value = "2" } });
var a2 = new List<Setting>(new Setting[] {
new Setting() { Key = "A", Value = "1" },
new Setting() { Key = "B", Value = "5" } });
var result = a2.Where(x => a1.Any(y => y.Key == x.Key && y.Value != x.Value)).ToList();
Console.WriteLine(result);
}
As you are comparing strings, you should be aware that ==
and !=
respectively always compares case-sensitive. So the keys need to be written in the same way in both lists (and also differences in case will be recognized as relevant differences). You can also use an overload of string.Compare to specify the comparison options in greater detail.
Upvotes: 6
Reputation: 460108
For performance reasons you could use a lookup:
var a1KeyLookup = A1.ToLookup(x => x.Key);
List<Setting> a2List = A2
.Where(a2 => a1KeyLookup[a2.Key].Any(a1 => a1.Value != a2.Value))
.ToList();
Here's your sample data:
IEnumerable<Setting> A1 = new List<Setting> {
new Setting{Key="A", Value="1"},
new Setting{Key="B", Value="2"},
};
IEnumerable<Setting> A2 = new List<Setting> {
new Setting{Key="A", Value="1"},
new Setting{Key="B", Value="5"},
};
var a1KeyLookup = A1.ToLookup(x => x.Key);
List<Setting> a2List = A2
.Where(a2 => a1KeyLookup[a2.Key].Any(a1 => a1.Value != a2.Value))
.ToList();
It returns as expected a list with a single item: Key="B", Value="5"
Upvotes: 2
Reputation: 410
var A1 = new List<Setting>(){new Setting(){Key = "A", Value = "1"}};
var A2 = new List<Setting>() { new Setting() { Key = "A", Value = "2" } };
var a1Keys = A1.Select(x => x.Key).ToList();
var dupKeys = A2.Where(x => a1Keys.Contains(x.Key)).Select(x=>x.Key);
var res = A2.Where(x => dupKeys.Contains(x.Key));
Upvotes: 2
Reputation: 35400
This should do it:
A2.Where(x => A1.Any(y => y.Key == x.Key && y.Value != x.Value))
BTW, your Setting class seems like reinventing the wheel. Dictionary
, Tuple
and NameValueCollection
can all do that for you.
Upvotes: 3