4

コレクションに値を追加できるようにする linq 拡張 (またはカスタム ディクショナリ、並べ替えられたリスト リスト、または最適なソリューション) を作成し、そのキーを「次に利用可能な」キーにします。

例えば:

int CreatedKey = IncrementDictionary.AddNext(myCustomer);

現在存在するキーが次の場合:

1
2
8
4
3

次に、キー 5 で myCustomer をディクショナリに追加し、そのキーを返します。

どう思いますか?

4

5 に答える 5

6
public static int AddNext(this Dictionary<int, string> dict)
{
    int min = dict.Keys.Min();
    int max = dict.Keys.Max();

    return Enumerable.Range(min, max-min).Except(dict.Keys).First();   
}

として使用します

int result = new Dictionary<int, string>(){ {1, "a"}, {2, "a"}, 
                                            {8, "a"}, {4, "a"}, 
                                                      {3, "a"}}.AddNext();

これで5になりますresult

于 2012-05-30T13:15:30.133 に答える
3

次に自動的に取得されたキーに追加するための Extension メソッドでSortedListを使用できます。

データ構造が数値キーを持つ任意のオブジェクトであると仮定すると、

以下はSortedListのExtensionMethodです

public static class SortedListExtensions
{
    ///Add item to sortedList (numeric key) to next available key item, and return key
    public static int AddNext<T>(this SortedList<int, T> sortedList, T item)
    {
        int key = 1; // Make it 0 to start from Zero based index
        int count = sortedList.Count;

        int counter=0;
        do
        {
            if (count == 0) break;
            int nextKeyInList = sortedList.Keys[counter++];

            if (key != nextKeyInList) break;

            key = nextKeyInList +1;

            if (count == 1 || counter == count  ) break;


            if (key != sortedList.Keys[counter])
                break;

        } while (true);

        sortedList.Add(key, item);
        return key;
    }

}

次のように使用できます

  SortedList<int, string> x = new SortedList<int, string>();

        x.Add(4, "BCD");
        x.Add(6, "BCD");

        x.AddNext("a");
        x.AddNext("b");
        x.AddNext("c");
        x.AddNext("d");
        x.AddNext("e");

        foreach (var item in x)
            Console.WriteLine(item.Key + " " + item.Value);

出力は

        1 a
        2 b
        3 c
        4 BCD
        5 d
        6 BCD
        7 e

ディクショナリまたはその他のデータ構造を使用できます。その場合は二重ループが必要になります。SortedList の場合、キーを検索する際のループが 1 回節約されます。このループはSortedList.AddBinarySearch Algorithm を使用する関数によって内部的に使用されます。

バイナリ検索は、すべての要素をループするよりも高速です (より大きなサイズのデータ​​の場合)。

于 2012-05-30T15:54:27.017 に答える
2

これが私の解決策でしたが、最初の解決策よりも短いものでしたが、そこからアイデアを得ることができました。

        Dictionary<int, string> x = new Dictionary<int, string>();
        x.Add(1, "a");
        x.Add(2, "a");
        x.Add(3, "a");
        x.Add(4, "a");
        x.Add(8, "a");
        Console.WriteLine((x.Keys.Where(k => !x.Keys.Contains(k + 1)).Min() + 1).ToString());
于 2012-05-30T13:11:45.117 に答える
1

このようなものを探していますか (明らかに 1000 個の要素しか含めることができません)? 他にも多くの解決策がある可能性がありますが、何をしたいのかを正確に伝えるのは困難です。とにかく、これは出発点になる可能性があります。

public class IncrementDictionary : Dictionary<int, object>
{
    private bool[] usedKeys = new bool[1000];

    public new void Add(int key, object value)
    {
        base.Add(key, value);
        usedKeys[key] = true;
    }

    public new void Clear()
    {
        base.Clear();
        usedKeys = new bool[1000];
    }

    public new object this[int key] 
    {
        get
        {
            return base[key];
        }
        set
        {
            base[key] = value;
            usedKeys[key] = true;
        }
    }

    public new bool Remove(int key)
    {
        usedKeys[key] = false;
        return base.Remove(key);
    }

    public int AddNext(object anObj)
    {
        int newKey = -1;
        for (int i = 1; i < 1000; i++)
            if (!usedKeys[i])
            {
                newKey = i;
                break;
            }
        if (newKey > 0)
            this.Add(newKey, anObj);
        return newKey;
    }
}
于 2012-05-30T13:21:18.123 に答える