web-dev-qa-db-ja.com

List <T>で特定の要素を見つける方法は?

私のアプリケーションはこのようなリストを使います。

List<MyClass> list = new List<MyClass>();

Addメソッドを使用して、MyClassの別のインスタンスがリストに追加されます。

MyClassは、とりわけ、以下のメソッドを提供します。

public void SetId(String Id);
public String GetId();

MyClassメソッドを使用してGetIdの特定のインスタンスを見つける方法はありますか。 Findメソッドがあることは知っていますが、これがここでうまくいくかどうかわかりませんか。

98
Robert Strauch

ラムダ式を使う

MyClass result = list.Find(x => x.GetId() == "xy");

注:C#には、プロパティの組み込み構文があります。 (Javaから慣れ親しんでいるように)getterメソッドとsetterメソッドを書く代わりに、

private string _id;
public string Id
{
    get
    {
        return _id;
    }
    set
    {
        _id = value;
    }
}

valueは、setアクセサでのみ知られている文脈上のキーワードです。プロパティに割り当てられた値を表します。

このパターンがよく使われるので、C#は 自動実装プロパティ を提供します。これらは上記のコードの短いバージョンです。ただし、補助変数は隠されていてアクセスできません(ただし、VBのクラス内からアクセスできます)。

public string Id { get; set; }

フィールドにアクセスしているかのようにプロパティを使用することができます。

var obj = new MyClass();
obj.Id = "xy";       // Calls the setter with "xy" assigned to the value parameter.
string id = obj.Id;  // Calls the getter.

プロパティを使用して、リスト内のアイテムをこのように検索します。

MyClass result = list.Find(x => x.Id == "xy"); 

読み取り専用プロパティが必要な場合は、自動実装プロパティも使用できます。

public string Id { get; private set; }

これにより、クラス内でIdを設定できますが、外部からは設定できません。派生クラスでも設定する必要がある場合は、セッターを保護することもできます。

public string Id { get; protected set; }

そして最後に、プロパティをvirtualとして宣言し、派生クラスでそれらをオーバーライドすることで、ゲッターとセッターに異なる実装を提供することができます。通常の仮想メソッドと同じです。


C#6.0(Visual Studio 2015、Roslyn)以降、インラインイニシャライザを使ってgetter-only auto-propertiesを書くことができます。

public string Id { get; } = "A07"; // Evaluated once when object is initialized.

代わりに、コンストラクタ内で取得専用プロパティを初期化することもできます。プライベートセッターで自動実装されたプロパティとは異なり、取得専用の自動プロパティはtrueの読み取り専用プロパティです。

これは読み書き自動プロパティでも動作します。

public string Id { get; set; } = "A07";

C#6.0からは、プロパティを式ボディメンバーとして書くこともできます。

public DateTime Yesterday => DateTime.Date.AddDays(-1); // Evaluated at each call.
// Instead of
public DateTime Yesterday { get { return DateTime.Date.AddDays(-1); } }

参照してください: 。NETコンパイラプラットフォーム( "Roslyn")
C#6の新しい言語機能

C#7. から始めて、getterとsetterの両方を式本体で書くことができます。

public string Name
{
    get => _name;                                // getter
    set => _name = value;                        // setter
}

この場合、セッターは式でなければならないことに注意してください。それは声明ではありえない。 C#では代入を式または文として使用できるため、上記の例は機能します。代入式の値は、代入自体が副作用となる代入値です。これにより、一度に複数の変数に値を代入できます。x = y = z = 0x = (y = (z = 0))と同等であり、ステートメントx = 0; y = 0; z = 0;と同じ効果があります。

var list = new List<MyClass>();
var item = list.Find( x => x.GetId() == "TARGET_ID" );

あるいは、たった1つしかなく、あなたがSingleOrDefaultのようなものがあなたが望むものであることを強制したいのならば

var item = list.SingleOrDefault( x => x.GetId() == "TARGET" );

if ( item == null )
    throw new Exception();
17
zellio

試してください:

 list.Find(item => item.id==myid);
9
Amritpal Singh

あるいは、 LINQ を使いたくない場合は、昔ながらの方法でできます。

List<MyClass> list = new List<MyClass>();
foreach (MyClass element in list)
{
    if (element.GetId() == "heres_where_you_put_what_you_are_looking_for")
    {

        break; // If you only want to find the first instance a break here would be best for your application
    }
}
4
Bjørn

LINQ 拡張子を使うこともできます。

string id = "hello";
MyClass result = list.Where(m => m.GetId() == id).First();
4
Guffa

匿名メソッドの構文を使って書かれた述語を使えば、問題を最も簡潔に解決できます。

MyClass found = list.Find(item => item.GetID() == ID);
3
David Heffernan
public List<DealsCategory> DealCategory { get; set; }
int categoryid = Convert.ToInt16(dealsModel.DealCategory.Select(x => x.Id));
0

検索条件を保持するための検索変数を作成できます。これはデータベースを使った例です。

 var query = from o in this.mJDBDataset.Products 
             where o.ProductStatus == textBox1.Text || o.Karrot == textBox1.Text 
             || o.ProductDetails == textBox1.Text || o.DepositDate == textBox1.Text 
             || o.SellDate == textBox1.Text
             select o;

 dataGridView1.DataSource = query.ToList();

 //Search and Calculate
 search = textBox1.Text;
 cnn.Open();
 string query1 = string.Format("select * from Products where ProductStatus='"
               + search +"'");
 SqlDataAdapter da = new SqlDataAdapter(query1, cnn);
 DataSet ds = new DataSet();
 da.Fill(ds, "Products");
 SqlDataReader reader;
 reader = new SqlCommand(query1, cnn).ExecuteReader();

 List<double> DuePayment = new List<double>();

 if (reader.HasRows)
 {

  while (reader.Read())
  {

   foreach (DataRow row in ds.Tables["Products"].Rows)
   {

     DuePaymentstring.Add(row["DuePayment"].ToString());
     DuePayment = DuePaymentstring.Select(x => double.Parse(x)).ToList();

   }
  }

  tdp = 0;
  tdp = DuePayment.Sum();                        
  DuePaymentstring.Remove(Convert.ToString(DuePaymentstring.Count));
  DuePayment.Clear();
 }
 cnn.Close();
 label3.Text = Convert.ToString(tdp + " Due Payment Count: " + 
 DuePayment.Count + " Due Payment string Count: " + DuePaymentstring.Count);
 tdp = 0;
 //DuePaymentstring.RemoveRange(0,DuePaymentstring.Count);
 //DuePayment.RemoveRange(0, DuePayment.Count);
 //Search and Calculate

ここで "var query"はあなたが検索変数を通して与えている検索基準を生成しています。それから "DuePaymentstring.Select"はあなたの与えられた基準に一致するデータを選択しています。あなたが問題を理解しているかどうか尋ねるのを遠慮しなくしてください。