web-dev-qa-db-ja.com

リストC#に重複する要素を追加しないでください

string[] lines3 = new string[100];
List<string> lines2 = new List<string>();
lines3 = Regex.Split(s1, @"\s*,\s*");

if (!lines2.Contains(lines3.ToString()))
{
    lines2.AddRange(lines3.Distinct().ToArray());
}

すべてのスペースなどをチェックしましたが、まだlines2 Listで重複した値を取得しています

ここで重複する値を削除する必要があります

20
vini

あなたのこのチェック:

_if (!lines2.Contains(lines3.ToString()))
_

無効です。 lines3.ToString()が提供するので、_lines2_に_System.String[]_が含まれているかどうかを確認しています。 _lines3_の項目が_lines2_に存在するかどうかを確認する必要があります。

_lines3_の各項目を繰り返して、_lines2_に存在するかどうかを確認してから追加できます。何かのようなもの。

_foreach (string str in lines3)
{
    if (!lines2.Contains(str))
        lines2.Add(str);
}
_

または、_lines2_が空のリストである場合は、次のように_lines3_の個別の値をリストに追加できます。

_lines2.AddRange(lines3.Distinct());
_

_lines2_には個別の値が含まれます。

29
Habib

Enumerable.Except を使用して、lines2にないlines3から個別のアイテムを取得できます。

lines2.AddRange(lines3.Except(lines2));

Lines2にlines3のすべてのアイテムが含まれている場合、何も追加されません。 BTWは、_Set<string> 2番目のシーケンスから個別のアイテムを取得し、それらのアイテムが最初のシーケンスに存在することを確認します。だから、それは非常に高速です。

37

HashSet<string>の代わりにList<string>を使用します。アイテムのチェックを提供する必要がないため、パフォーマンスを向上させる準備ができています。コレクションがあなたのためにそれを管理します。これは、listsetの違いです。サンプルの場合:

HashSet<string> set = new HashSet<string>();

set.Add("a");
set.Add("a");
set.Add("b");
set.Add("c");
set.Add("b");
set.Add("c");
set.Add("a");
set.Add("d");
set.Add("e");
set.Add("e");

var total = set.Count;

合計は5で、値はabcdeです。

List<T>の実装は、ネイティブには提供しません。できますが、このコントロールを提供する必要があります。サンプルの場合、このextension method

public static class CollectionExtensions
{
    public static void AddItem<T>(this List<T> list, T item)
    {
       if (!list.Contains(item))
       {
          list.Add(item);
       }
    }
}

そしてそれを使用します:

var list = new List<string>();
list.AddItem(1);
list.AddItem(2);
list.AddItem(3);
list.AddItem(2);
list.AddItem(4);
list.AddItem(5);
24
Felipe Oriani

リスト内で重複したくない場合は、 HashSet を使用します。そうすれば、あなたのコードを読んでいる他の誰にもあなたの意図が明確になり、HashSetがあなたがしようとしていることを既に処理するので、書くコードが少なくなります。

3
Ian Mercer

単純なUnion + Distinctを使用できます。

var lines = lines2.Union(lines3).Distinct();

これにより、2番目のリストのすべてのアイテムが最初のリストに追加され、結合されたリストのすべての一意の文字列が返されます。大きなリストではうまく機能しない可能性がありますが、簡単です。

参照: http://msdn.Microsoft.com/en-us/library/bb341731.aspx

3
Tieson T.

チェックが機能する場合は、すべてのアイテムを追加するか、まったく追加しないかのいずれかです。ただし、配列でToStringメソッドを呼び出すと、配列の内容ではなくデータ型の名前が返され、Containsメソッドはコレクションのコレクションではなく単一のアイテムのみを検索できますとにかくアイテム。

配列内の各文字列を確認する必要があります。

string[] lines3;
List<string> lines2 = new List<string>();

lines3 = Regex.Split(s1, @"\s*,\s*");

foreach (string s in lines3) {
  if (!lines2.Contains(s)) {
    lines2.Add(s);
  }
}

ただし、空のリストから開始する場合は、Distinctメソッドを使用して重複を削除できます。必要なコードは1行のみです。

List<string> lines2 = Regex.Split(s1, @"\s*,\s*").Distinct().ToList();
2
Guffa

個別の値をコレクションに保存する場合は、 HashSet Class を試してください。重複する値が自動的に削除され、コーディング時間が節約されます。 :)

1
Erxin

#Felipe Orianiからヒントを得て、ここで共有したい拡張機能を作成しました。

public static class CollectionExtension
{
    public static void AddUniqueItem<T>(this List<T> list, T item, bool throwException)
    {
        if (!list.Contains(item))
        {
            list.Add(item);
        }
        else if(throwException)
        {
            throw new InvalidOperationException("Item already exists in the list");
        }
    }
    public static bool IsUnique<T>(this List<T> list, IEqualityComparer<T> comparer)
    {
        return list.Count == list.Distinct(comparer).Count();
    }
    public static bool IsUnique<T>(this List<T> list)
    {
        return list.Count == list.Distinct().Count();
    }
}
0
Kasim Husaini

良い方法ではありませんが、ちょっとした簡単な修正方法です。リスト全体に重複エントリがあるかどうかを確認するためにboolを使用してください。

bool containsKey;
string newKey;

    public void addKey(string newKey){

         foreach(string key in MyKeys){
           if(key == newKey){
             containsKey = true;
          }
         }

      if(!containsKey){
       MyKeys.add(newKey);
     }else{
       containsKey = false;
     }

    }
0
Amir Javed

HashSetとともにListを使用します。

_List<string> myList = new List<string>();
HashSet<string> myHashSet = new HashSet<string>();

public void addToList(string s) {
    if (myHashSet.Add(s)) {
        myList.Add(s);
    }
}
_

myHashSet.Add(s)は、trueが存在しない場合、sを返します。

0

HashSetを使用してください。

こちらをご覧ください: http://www.dotnetperls.com/hashset

0
danvasiloiu