code

목록에 고유 항목 만 추가

codestyles 2020. 11. 7. 10:00
반응형

목록에 고유 항목 만 추가


네트워크를 통해 자신을 알리는 원격 장치를 목록에 추가하고 있습니다. 이전에 추가하지 않은 경우에만 장치를 목록에 추가하고 싶습니다.

알림은 비동기 소켓 리스너를 통해 전달되므로 장치를 추가하는 코드를 여러 스레드에서 실행할 수 있습니다. 나는 내가 뭘 잘못하고 있는지 확실하지 않지만 내가 시도하는 것과 상관없이 중복으로 끝납니다. 여기 내가 현재 가지고있는 것 .....

lock (_remoteDevicesLock)
{
    RemoteDevice rDevice = (from d in _remoteDevices
                            where d.UUID.Trim().Equals(notifyMessage.UUID.Trim(), StringComparison.OrdinalIgnoreCase)
                            select d).FirstOrDefault();
     if (rDevice != null)
     {
         //Update Device.....
     }
     else
     {
         //Create A New Remote Device
         rDevice = new RemoteDevice(notifyMessage.UUID);
         _remoteDevices.Add(rDevice);
     }
}

요구 사항이 중복되지 않도록하려면 HashSet 을 사용해야합니다 .

HashSet.Add항목이 이미 존재하면 false 를 반환 합니다 (중요한 경우에도).

@pstrjds가 아래 (또는 여기 )에 연결하는 생성자 를 사용하여 같음 연산자를 정의하거나 RemoteDevice( GetHashCode& Equals) 에서 같음 메서드를 구현해야합니다 .


//HashSet allows only the unique values to the list
HashSet<int> uniqueList = new HashSet<int>();

var a = uniqueList.Add(1);
var b = uniqueList.Add(2);
var c = uniqueList.Add(3);
var d = uniqueList.Add(2); // should not be added to the list but will not crash the app

//Dictionary allows only the unique Keys to the list, Values can be repeated
Dictionary<int, string> dict = new Dictionary<int, string>();

dict.Add(1,"Happy");
dict.Add(2, "Smile");
dict.Add(3, "Happy");
dict.Add(2, "Sad"); // should be failed // Run time error "An item with the same key has already been added." App will crash

//Dictionary allows only the unique Keys to the list, Values can be repeated
Dictionary<string, int> dictRev = new Dictionary<string, int>();

dictRev.Add("Happy", 1);
dictRev.Add("Smile", 2);
dictRev.Add("Happy", 3); // should be failed // Run time error "An item with the same key has already been added." App will crash
dictRev.Add("Sad", 2);

수락 된 답변에 따르면 HashSet에는 주문이 없습니다. 주문이 중요한 경우 목록을 계속 사용하고 추가하기 전에 항목이 포함되어 있는지 확인할 수 있습니다.

if (_remoteDevices.Contains(rDevice))
    _remoteDevices.Add(rDevice);

사용자 정의 클래스 / 객체에서 List.Contains ()를 수행하려면 IEquatable<T>사용자 정의 클래스에서 구현 하거나 Equals. GetHashCode클래스 에서도 구현하는 것이 좋습니다 . 이것은 https://msdn.microsoft.com/en-us/library/ms224763.aspx 의 설명서에 따릅니다.

public class RemoteDevice: IEquatable<RemoteDevice>
{
    private readonly int id;
    public RemoteDevice(int uuid)
    {
        id = id
    }
    public int GetId
    {
        get { return id; }
    }

    // ...

    public bool Equals(RemoteDevice other)
    {
        if (this.GetId == other.GetId)
            return true;
        else
            return false;
    }
    public override int GetHashCode()
    {
        return id;
    }
}

확장 메서드로 작성하여 일반성을 얻을 수 있으며 선택적 사용자 지정 비교자를 전달할 수 있습니다.

/// <summary>
/// Generates a new list with only distinct items preserving original ordering.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="comparer"></param>
/// <returns></returns>
public static IList<T> ToUniqueList<T>(this IList<T> list, IEqualityComparer<T> comparer = null)
{
    bool Contains(T x) => comparer == null ? list.Contains(x) : list.Contains(x, comparer);

    return list.Where(entity => !Contains(entity)).ToList();
}

참고URL : https://stackoverflow.com/questions/13498111/only-add-unique-item-to-list

반응형