web-dev-qa-db-ja.com

辞書の最後の要素を取得しますか?

私の辞書:

Dictionary<double, string> dic = new Dictionary<double, string>();

辞書の最後の要素を返すにはどうすればよいですか?

23
subprime

ラストとはどういう意味ですか?最後の付加価値という意味ですか?

Dictionary<TKey,TValue>クラスは、順序付けられていないコレクションです。アイテムを追加および削除すると、最初と最後の要素と見なされるものが変更される可能性があります。したがって、Last要素を追加する方法はありません。

SortedDictionary<TKey,TValue>の形式で利用できる順序付けされた辞書クラスがあります。しかし、これはキーの比較に基づいて順序付けられ、値が追加された順序ではありません。

[〜#〜]編集[〜#〜]

いくつかの人々は、次のLINQスタイルのアプローチを使用して言及しています

var last = dictionary.Values.Last();

この方法の使用には十分注意してください。これは、Valuesコレクションの最後の値を返します。これは、辞書に追加した最後の値である場合とそうでない場合があります。それはおそらくそれがそうであるほどではない可能性が高いです。

52
JaredPar

辞書は順不同のコレクションです-そのため、最初または最後の要素という概念はありません。辞書のように動作し、アイテムの挿入順序を維持するクラスを探している場合は、 OrderedDictionary の使用を検討してください。

アイテムを並べ替えるコレクションを探している場合は、 _SortedDictionary<TKey,TValue>_ の使用を検討してください。

既存の辞書があり、並べ替え順序が指定された「最後の」要素を探している場合は、linqを使用してコレクションを並べ替えることができます。

_myDictionary.Values.OrderBy( x => x.Key ).Last();
_

Dictionary.Keys.Last()を使用する場合は注意が必要です。キーリストは、キーのタイプのデフォルトのIComparerを使用してソートされますが、取得する値は期待した値とは異なる場合があります。

21
LBushkin

私はこの質問が古すぎて賛成を得ることはできないことを知っていますが、私は答えが好きではなかったので、将来の読者に別のオプションを提供することを期待して自分の質問を投稿します。

次のdid notは.NET 4.0で動作しました。

myDictionary.Values.OrderBy( x => x.Key ).Last();

問題は、「x」がディクショナリ内の値を表し、値にキーがないことです(ディクショナリにはキーが格納され、ディクショナリ値にはありません)。また、テクニックの使い方を間違えているかもしれません。

どちらの方法でも、辞書全体の並べ替えであるため、このソリューションは、大規模な辞書の場合、おそらくO(n log n) CSユーザーにとっては低速になります。 /ちょうど1つのエントリを取得します。これは、特定の1つの映画を見つけるためにDVDコレクション全体を並べ替えるようなものです。


var lastDicVal = dic.Values.Last();

悪い考えとして定着しています。実際には、このソリューションは、Microsoftのディクショナリの実装により、ほとんどの場合実際に機能しますが、ソフトウェアエンジニアリングの用語では意味がなく、信頼するべきではありません。それが永遠に続くすべての時間で機能するとしても、それはずさんな、安全でないコーディング慣行を表します。


私の解決策は次のとおりです:

var lastValue = dic[dic.Keys.Max()];

Keys.max()関数はO(n log n)の代わりにO(n)をソートするよりもはるかに高速です。 O(n)であっても遅くなるほどパフォーマンスが重要である場合、最後に挿入されたキーは、dic.Keys.Max()を置き換えるために使用される別の変数で追跡できます。 、これはルックアップ全体を作成しますO(1)加えて、最後に挿入されたエントリの追跡に存在するオーバーヘッドがあればそれを加えます。

7
Charles Burns

.NET 3.5を使用している場合は、次を参照してください。

 dic.Keys.Last()

ただし、予測可能な順序が必要な場合は、次を使用します。

IDictionary<int, string> dic = new SortedDictionary<int, string>();
5
Chris Doggett

カスタムコレクションのAddメソッドで参照を含むカスタムコレクションを作成することを検討してください。これにより、要件に応じて、最後に追加されたキー/値(またはその両方)を含むプライベートフィールドが設定されます。

次に、これを返すLast()メソッドがあります。以下は、私が何を意味するかを示すための概念実証クラスです(インターフェイスの実装の欠如など、サンプルコードです)。

public class LastDictionary<TKey, TValue>
{
    private Dictionary<TKey, TValue> dict;

    public LastDictionary()
    {
        dict = new Dictionary<TKey, TValue>();
    }

    public void Add(TKey key, TValue value)
    {
        LastKey = key;
        LastValue = value;
        dict.Add(key, value);
    }

    public TKey LastKey
    {
        get; private set;
    }

    public TValue LastValue
    {
        get; private set;
    }
}
3
RichardOD

代わりに:

Dictionary<double, string>

...使用できます:

List<KeyValuePair<double, string>>

これにより、インデクサーを使用して、キーではなく順序で要素にアクセスできます。

3
Erick

docs から:

列挙のために、ディクショナリ内の各アイテムは、値とそのキーを表すKeyValuePair構造として扱われます。 アイテムが返される順序は未定義です

したがって、Dictionaryを使用して最後の要素を返すことはできないと思います。

別のコレクションを使用してください。多分SortedDictionary ...

1
bruno conde

値だけが必要な場合は、これでうまくいくはずです(LINQを使用できる場合)。

dic.Values.Last()
0
Lance Harper

あなたは使うことができます:

dic.Last()

しかし、辞書には実際には最後の要素はありません(内部のペアは特定の方法で順序付けされていません)。最後の項目は常に同じですが、どの要素であるかは明確ではありません。

0
Jake Pearson

.Net 3.5の場合:

string lastItem = dic.Values.Last()
string lastKey = dic.Keys.Last()

...しかし、辞書は順序付けされていないので、値が同じ順序のままであることは当てにできません。

0
Meta-Knight

辞書は順番にアクセスするためのものではないため、最初、最後には意味がありません。最高のキーでインデックス付けされた値が必要ですか?

Dictionary<double, string> dic = new Dictionary<double, string>();
double highest = double.MinValue;
string result = null;
foreach(double d in dic.keys)
{
   if(d > highest)
   {
      result = dic[d];
      highest = d;
   }
}
0
Hardwareguy

他のほとんどの回答が示唆するようにLinqを使用する代わりに、Countプロパティを介して任意のCollectionオブジェクトの最後の要素にアクセスできます(詳細については ICollection.Countプロパティ を参照)。

Countを使用してコレクション(辞書を含む)の最後の要素にアクセスする方法の例については、ここのコードを参照してください。

Dictionary<double, string> dic = new Dictionary<double, string>();
var lastElementIndex = dic.Count - 1;
var lastElement = dic[lastElementIndex];

これはキーではなく最後の[〜#〜] value [〜#〜]を返すことに注意してください。

0
Blairg23