linq .Net Core,合并两个列表,删除无效条目并保留原始列表中的值

zdwk9cvp  于 2022-12-06  发布在  .NET
关注(0)|答案(1)|浏览(217)

I have a default list of attributes and in incoming list of attributes. I need to remove any items from the incoming list that do now match the Name in the default list. I have tried many different LINQ queries, but have not been able to accomplish this task.
Default List:

Attributes[] defaultAttributes = 
{
    new ProfileAttributes() { Name = "FirstName", Include = false, Required = false },
    new ProfileAttributes() { Name = "MiddleName", Include = false, Required = false },
    new ProfileAttributes() { Name = "HomeCountry", Include = false, Required = false },
...

I want to merge the two lists and remove any items where the Name of the incoming list does not match the default list.
For example in the following remove Favorite color because it is an invalid name and preserve the required values.

Attributes[] incomingAttributes = 
{
    new ProfileAttributes() { Name = "FavoriteColor", Required = true },
    new ProfileAttributes() { Name = "MiddleName", Required = false},
    new ProfileAttributes() { Name = "HomeCountry", Required = true },

Most incoming lists will not have "Include" So I need to add that and set it to true if it is in the incoming list, otherwise false. I have done that with the following, but interested if there is a way to combine this with the merge.

Revised, I used the following solution: I used lists instead of array lists. I found this easier to loop through and bind to checkboxes on the form

Attributes[] defaultAttributes

to

List<ProfileAttributes> defaultAttributes = new List<ProfileAttributes>()

Inside the loop for my form:

<input type="checkbox"for="myModel.ProfileAttributes[i].Include"

I created an empty list:

List<ProfileAttributes> validListAttributes = new();

Then I created a loop. If the name is valid add it to the empty list and add the Include attribute:

foreach (var a in myModel.ProfileAttributes) //incomingAttributes
 {
    if (defaultAttributes.Any(d => d.Name == a.Name))
    {
        a.Include = true;
        validListAttributes.Add(a);
    }
 }

Then another loop to add missing attributes because all attributes must be display on the form:

foreach (var d in defaultAttributes)
{
   if (!validListAttributes.Any(v => v.Name == d.Name))
   {
      validListAttributes.Add(d);
    }
}

Then update the model with the valid list containing all attributes:

myModel.ProfileAttributes = validListAttributes.ToList();
p1tboqfb

p1tboqfb1#

使用一个通用的IEqualityComparer,它的工作是比较流程中涉及的示例的Name属性,这样做会容易得多。
因此,让我们为Attributes类定义一个IEqualityComparer

public class ProfileAttributesComparer : IEqualityComparer<ProfileAttributes>
{
    public bool Equals(ProfileAttributes obj1, ProfileAttributes obj2)
    {
        if(obj1 == null && obj2 == null)
            return true;
        if(obj1 == null || obj2 == null)
            return false;
            
        var result = string.Compare(obj1.Name, obj2.Name,  
                         StringComparison.CurrentCultureIgnoreCase);
        return result == 0;
    }
    public int GetHashCode(ProfileAttributes obj)
    {
        return obj.Name.GetHashCode();
    }
}

现在,您可以处理 incomingAttributes 中名称与 defaultAttributes 中示例相同的元素,并将属性Include更改为true

var result = incomingAttributes
    .Where(x => defaultAttributes.Contains(x, new ProfileAttributesComparer()))
    .Select(p => { p.Include = true; return p;});
  • result* 变量仅包含具有相同名称的项,但 incomingAttributes 列表仍有三个项,其中两个项的Include属性更改为true。

相关问题