web-dev-qa-db-ja.com

List <>の最後の要素を見つけるにはどうすればいいですか?

以下は私のコードからの抜粋です。

public class AllIntegerIDs 
{
    public AllIntegerIDs() 
    {            
        m_MessageID = 0;
        m_MessageType = 0;
        m_ClassID = 0;
        m_CategoryID = 0;
        m_MessageText = null;
    }

    ~AllIntegerIDs()
    {
    }

    public void SetIntegerValues (int messageID, int messagetype,
        int classID, int categoryID)
    {
        this.m_MessageID = messageID;
        this.m_MessageType = messagetype;
        this.m_ClassID = classID;
        this.m_CategoryID = categoryID;
    }

    public string m_MessageText;
    public int m_MessageID;
    public int m_MessageType;
    public int m_ClassID;
    public int m_CategoryID;
}

私は私のmain()関数コードで以下を使用しようとしています:

List<AllIntegerIDs> integerList = new List<AllIntegerIDs>();

/* some code here that is ised for following assignments*/
{
   integerList.Add(new AllIntegerIDs());
   index++;
   integerList[index].m_MessageID = (int)IntegerIDsSubstring[IntOffset];
   integerList[index].m_MessageType = (int)IntegerIDsSubstring[IntOffset + 1];
   integerList[index].m_ClassID = (int)IntegerIDsSubstring[IntOffset + 2];
   integerList[index].m_CategoryID = (int)IntegerIDsSubstring[IntOffset + 3];
   integerList[index].m_MessageText = MessageTextSubstring;
}

問題はここにあります:私はforループを使って私のリストのすべての要素を印刷しようとしています:

for (int cnt3 = 0 ; cnt3 <= integerList.FindLastIndex ; cnt3++) //<----PROBLEM HERE
{
   Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n", integerList[cnt3].m_MessageID,integerList[cnt3].m_MessageType,integerList[cnt3].m_ClassID,integerList[cnt3].m_CategoryID, integerList[cnt3].m_MessageText);
}

最後の要素を見つけて、forループのcnt3と同じものにして、リストのすべてのエントリを出力します。リストの各要素は、コードサンプルで前述したように、クラスAllIntegerIDsのオブジェクトです。リストの最後の有効なエントリを見つける方法は?

IntegerList.Find(integerList []。m_MessageText == null;のようなものを使用する必要があります。

私がそれを使用するなら、それは0からどんな最大値までも及ぶインデックスを必要とするでしょう。私が使用するつもりはない別のforループを使用する必要があるということです。もっと短い/もっと良い方法はありますか?

ありがとう、Viren

144
zack

あなたがちょうどリストの最後の項目にアクセスしたいならば、あなたはすることができます

var item = integerList[integerList.Count - 1];

リスト内のアイテムの総数を取得するには、Countプロパティを使用できます。

var itemCount = integerList.Count;
175
Jared

コレクションの最後の項目を取得するには、LastOrDefault()およびLast()を使用します。拡張メソッド

var lastItem = integerList.LastOrDefault();

OR

var lastItem = integerList.Last();

using System.Linq;を追加することを忘れないでください。そうしないと、このメソッドは利用できなくなります。

228

リストの最後の要素に安全に対処する方法、質問の根本にたどり着くことができます...

想定して

List<string> myList = new List<string>();

それから

//NOT safe on an empty list!
string myString = myList[myList.Count -1];

//equivalent to the above line when Count is 0, bad index
string otherString = myList[-1];

あなたが最初にリストが空でないことを保証しない限り、 "count-1"は悪い習慣です。

それをする以外に空のリストをチェックすることを回避する便利な方法はありません。

私が考えることができる最短の方法は

string myString = (myList.Count != 0) ? myList [ myList.Count-1 ] : "";

あなたはすべての外に出て、常にtrueを返すデリゲートを作り、それを最後の値(あるいはリストが空の場合はデフォルトで構築されたvalye)を返すFindLastに渡すことができます。この関数はリストの最後から始まるので、メソッドは通常O(n)であるにもかかわらず、Big O(1)または一定時間になります。

//somewhere in your codebase, a strange delegate is defined
private static bool alwaysTrue(string in)
{
    return true;
}

//Wherever you are working with the list
string myString = myList.FindLast(alwaysTrue);

デリゲート部分を数えるとFindLastメソッドは醜いですが、それは一か所で宣言する必要があるだけです。リストが空の場合は、stringに対してリストタイプ ""のデフォルトの構築値を返します。 alwaysTrueデリゲートをさらに一歩進めて、文字列型ではなくテンプレートにするとより便利です。

16
JFDev

変化する

for (int cnt3 = 0 ; cnt3 <= integerList.FindLastIndex ; cnt3++)

for (int cnt3 = 0 ; cnt3 < integerList.Count; cnt3++)
4
Eric J.

For forリストの代わりにFor Eachを使用してみてください。それはずっと簡単になります。

3
RiddlerDev
int lastInt = integerList[integerList.Count-1];
3
Dan Diplo

あなたは最初にリストの要素の数を数えることによってそれを見つけることができます。

int count = list.Count();

それから、リストの最後の要素を取得するためにcount - 1にインデックスを付けることができます。

int lastNumber = list[count - 1];

リストのCountプロパティを使用しないのはなぜですか。

for(int cnt3 = 0; cnt3 < integerList.Count; cnt3++)
2
Brandon

Countプロパティを使用してください。最後のインデックスはCount - 1になります。

for (int cnt3 = 0 ; cnt3 < integerList.Count; cnt3++)
2
Spencer Ruport

私はforeachがもっと簡単なようなものになるだろうということに同意しなければならないでしょう

foreach(AllIntegerIDs allIntegerIDs in integerList)
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n", allIntegerIDs.m_MessageID,
allIntegerIDs.m_MessageType,
allIntegerIDs.m_ClassID,
allIntegerIDs.m_CategoryID,
allIntegerIDs.m_MessageText);
}

また、パブリックフィールドの代わりに、あなたの情報にアクセスするためのプロパティを追加することをお勧めします。あなたの.netバージョンによってはpublic int MessageType {get; set;}のように追加でき、パブリックフィールドからm_を削除できます。

0
Michael Ciba

これはあなたの役に立つと思います。チェックしてください

    TaxRangers[TaxRangers.Count]. max
0
sandeep sandy

元の質問とは関係なく、リストに複数回インデックスを付けるのではなく、ローカル変数への参照をキャプチャすると、パフォーマンスが向上します。

AllIntegerIDs ids = new AllIntegerIDs();
ids.m_MessageID = (int)IntegerIDsSubstring[IntOffset];
ids.m_MessageType = (int)IntegerIDsSubstring[IntOffset + 1];
ids.m_ClassID = (int)IntegerIDsSubstring[IntOffset + 2];
ids.m_CategoryID = (int)IntegerIDsSubstring[IntOffset + 3];
ids.m_MessageText = MessageTextSubstring;
integerList.Add(ids);

そしてforループの中で:

for (int cnt3 = 0 ; cnt3 < integerList.Count ; cnt3++) //<----PROBLEM HERE
{
   AllIntegerIDs ids = integerList[cnt3];
   Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n",
      ids.m_MessageID,ids.m_MessageType,ids.m_ClassID,ids.m_CategoryID, ids.m_MessageText);
}
0
dahlbyk