객체가 이미 목록에 있는지 확인하는 방법
목록이 있습니다
List<MyObject> myList
목록에 항목을 추가하고 있으며 해당 개체가 이미 목록에 있는지 확인하고 싶습니다.
그래서 이것을하기 전에 :
myList.Add(nextObject);
nextObject가 이미 목록에 있는지 확인하고 싶습니다.
"MyObject"개체에는 여러 속성이 있지만 비교는 두 속성의 일치를 기반으로합니다.
이 "MyObject"목록에 새 "MyObject"를 추가하기 전에 확인하는 가장 좋은 방법은 무엇입니까?
내가 생각한 유일한 해결책은 목록에서 사전으로 변경 한 다음 키를 속성의 연결된 문자열로 만드는 것입니다 (조금 불분명 해 보입니다).
목록이나 LINQ 또는 다른 것을 사용하는 다른 클리너 솔루션이 있습니까?
특정 상황의 필요에 따라 다릅니다. 예를 들어, 사전 접근 방식은 다음과 같이 가정하면 매우 좋습니다.
- 목록이 비교적 안정적입니다 (사전이 최적화되지 않은 삽입 / 삭제가 많지 않음).
- 목록이 상당히 큽니다 (그렇지 않으면 사전의 오버 헤드가 무의미합니다).
위의 내용이 귀하의 상황에 맞지 않으면 다음을 사용하십시오 Any()
.
Item wonderIfItsPresent = ...
bool containsItem = myList.Any(item => item.UniqueProperty == wonderIfItsPresent.UniqueProperty);'
일치하는 항목을 찾거나 끝에 도달 할 때까지 목록을 통해 열거됩니다.
Contains 메서드를 사용하기 만하면됩니다 . 등식 함수를 기반으로 작동합니다.Equals
bool alreadyExist = list.Contains(item);
이 두 가지 속성을 유지 관리 할 수 있다면 다음을 수행 할 수 있습니다.
bool alreadyExists = myList.Any(x=> x.Foo=="ooo" && x.Bar == "bat");
이 경우 목록이 필요합니까? 많은 항목으로 목록을 채우는 경우 성능이 myList.Contains
또는로 인해 저하됩니다 myList.Any
. 런타임은 2 차가됩니다. 더 나은 데이터 구조 사용을 고려할 수 있습니다. 예를 들면
public class MyClass
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
public class MyClassComparer : EqualityComparer<MyClass>
{
public override bool Equals(MyClass x, MyClass y)
{
if(x == null || y == null)
return x == y;
return x.Property1 == y.Property1 && x.Property2 == y.Property2;
}
public override int GetHashCode(MyClass obj)
{
return obj == null ? 0 : (obj.Property1.GetHashCode() ^ obj.Property2.GetHashCode());
}
}
다음과 같은 방식으로 HashSet을 사용할 수 있습니다.
var set = new HashSet<MyClass>(new MyClassComparer());
foreach(var myClass in ...)
set.Add(myClass);
Of course, if this definition of equality for MyClass
is 'universal', you needn't write an IEqualityComparer
implementation; you could just override GetHashCode
and Equals
in the class itself.
Another point to mention is that you should ensure that your equality function is as you expect. You should override the equals method to set up what properties of your object have to match for two instances to be considered equal.
Then you can just do mylist.contains(item)
Here is a quick console app to depict the concept of how to solve your issue.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
public class myobj
{
private string a = string.Empty;
private string b = string.Empty;
public myobj(string a, string b)
{
this.a = a;
this.b = b;
}
public string A
{
get
{
return a;
}
}
public string B
{
get
{
return b;
}
}
}
class Program
{
static void Main(string[] args)
{
List<myobj> list = new List<myobj>();
myobj[] objects = { new myobj("a", "b"), new myobj("c", "d"), new myobj("a", "b") };
for (int i = 0; i < objects.Length; i++)
{
if (!list.Exists((delegate(myobj x) { return (string.Equals(x.A, objects[i].A) && string.Equals(x.B, objects[i].B)) ? true : false; })))
{
list.Add(objects[i]);
}
}
}
}
}
Enjoy!
Edit: I had first said:
What's inelegant about the dictionary solution. It seems perfectly elegant to me, esp since you only need to set the comparator in creation of the dictionary.
Of course though, it is inelegant to use something as a key when it's also the value.
Therefore I would use a HashSet. If later operations required indexing, I'd create a list from it when the Adding was done, otherwise, just use the hashset.
Simple but it works
MyList.Remove(nextObject)
MyList.Add(nextObject)
or
if (!MyList.Contains(nextObject))
MyList.Add(nextObject);
참고URL : https://stackoverflow.com/questions/3435089/how-to-check-if-object-already-exists-in-a-list
'programing tip' 카테고리의 다른 글
c # 목록을 뒤집으려고 (0) | 2020.09.23 |
---|---|
두 시간의 차이를 초 단위로 확인 (0) | 2020.09.23 |
jQuery를 사용하여 JavaScript 객체에서 항목 추가 / 제거 (0) | 2020.09.23 |
iPhone 앱을위한 기성 캘린더 컨트롤이 있습니까? (0) | 2020.09.22 |
PHP에서 PUT / DELETE 인수 처리 (0) | 2020.09.22 |