C# 发现';下一个可用';输入字典或相关集合
我想编写一个linq扩展(或自定义字典、排序列表或任何最好的解决方案),允许我向集合添加一个值,其键为“下一个可用”键 例如:C# 发现';下一个可用';输入字典或相关集合,c#,.net,linq,c#-4.0,collections,C#,.net,Linq,C# 4.0,Collections,我想编写一个linq扩展(或自定义字典、排序列表或任何最好的解决方案),允许我向集合添加一个值,其键为“下一个可用”键 例如: int CreatedKey = IncrementDictionary.AddNext(myCustomer); 如果当前存在的密钥如下所示: 1 2 8 4 3 然后它会将myCustomer添加到字典中,并使用5键返回该键 你觉得怎么样?我的解决方案比第一个短,但你可以从中得到一个想法 Dictionary<int, string>
int CreatedKey = IncrementDictionary.AddNext(myCustomer);
如果当前存在的密钥如下所示:
1
2
8
4
3
然后它会将myCustomer添加到字典中,并使用5键返回该键
你觉得怎么样?我的解决方案比第一个短,但你可以从中得到一个想法
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());
Dictionary x=newdictionary();
x、 添加(1,“a”);
x、 添加(2,“a”);
x、 添加(3,“a”);
x、 添加(4,“a”);
x、 添加(8,“a”);
Console.WriteLine((x.Keys.Where(k=>!x.Keys.Contains(k+1)).Min()+1.ToString());
公共静态int AddNext(本词典)
{
int min=dict.Keys.min();
int max=dict.Keys.max();
返回可枚举的.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();
int result=newdictionary(){{1,“a”},{2,“a”},
{8,“a”},{4,“a”},
{3,“a”}}.AddNext();
这里的
结果是5。您是否正在寻找类似的东西(它显然只能包含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;
}
}
公共类增量字典:字典
{
私有bool[]usedKeys=新bool[1000];
public new void Add(int键,对象值)
{
添加(键、值);
usedKeys[键]=真;
}
公共新空白清除()
{
base.Clear();
usedKeys=新布尔值[1000];
}
公共新对象此[int key]
{
得到
{
返回基[键];
}
设置
{
基[键]=值;
usedKeys[键]=真;
}
}
公共新布尔删除(int键)
{
usedKeys[键]=假;
返回底座。移除(键);
}
公共int AddNext(对象anObj)
{
int newKey=-1;
对于(int i=1;i<1000;i++)
如果(!usedKeys[i])
{
newKey=i;
打破
}
如果(newKey>0)
添加(newKey,anObj);
返回newKey;
}
}
您可以使用扩展方法添加到下一个自动检索的密钥
假设数据结构是任何对象,带有数字键
以下是SortedList的扩展方法
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,搜索键时会保存一个循环。此循环由使用BinarySearch算法的函数在内部使用
二进制搜索比循环所有元素更快(对于较大的数据)。好吧。。。这是个老问题,但我想回答
Nikhil Agrawal的代码可能会有所改进,因为如果您有一个空集合,则必须指定最小值。因此,代码变成:
public static int FirstFree(Dictionary<int, Guid> dict, int minumum)
{
int min = dict.Count == 0
? minumum //use passed minimum if needed
: dict.Keys.Min(); //use real minimum
int max = dict.Count > 1
? dict.Keys.Max() + 2 //two steps away from maximum, avoids exceptions
: min + 2; //emulate data presence
return Enumerable.Range(min, max).Except(dict.Keys).First();
}
publicstaticintfirstfree(Dictionary dict,intminumum)
{
int min=dict.Count==0
?最小值//如果需要,使用通过的最小值
:dict.Keys.Min();//使用实最小值
int max=指令计数>1
?dict.Keys.Max()+2//距离最大值两步,避免异常
:min+2;//模拟数据存在
返回可枚举的.Range(min,max).Except(dict.Keys).First();
}
但是,如果您在定义的范围内工作,您还应该知道是否有空间存储值。这可以是:
public static int? FirstFree(Dictionary<int, Guid> dict, int min, int max)
{
if (max <= min)
throw new Exception($"Specified range is invalid (must be max > min)");
if (max - min + 1 == dict.Count)
//no space left
return null;
return Enumerable.Range(min, max).Except(dict.Keys).First();
}
公共静态int?FirstFree(字典dict、int-min、int-max)
{
如果(max我想问题是什么还不清楚。我也不认为这会成为一个特别有用的数据结构,因为对象引用或哈希代码/相等方法的组合足以识别对象。嗨,威廉,看起来你的问题属于。你会在该网站上发现更好的响应率,因为它是我本来是想问这类问题的。@dtb但是OP要求人们评价(或回顾)他的想法,这里没有问题,他只是想问一个问题review@DoctaJonez:哪种想法?在我看来,这些问题似乎是OP在寻求满足其要求的代码。@dtb它的内容是“我在做什么,你怎么看?”.听起来像是一个你熟悉的复习问题?@dtb是的;)谢谢你的帮助:)虽然我的答案真的很好:)哇+1对你来说NikHil:)你用一行击中了答案:)另一个伟大的@dtb例子:我知道,但这在这里是怎么应用的?你能吗explain@dtb为什么你总是说不管是谁,施莱米尔:)他是你的大学教授吗?你在字典里插入的每一个键,你都必须在查找下一个密钥时需要多做一些工作。这是非常低效的。应该使用适当的数据结构来解决问题,而不是使用暴力。
1 a
2 b
3 c
4 BCD
5 d
6 BCD
7 e
public static int FirstFree(Dictionary<int, Guid> dict, int minumum)
{
int min = dict.Count == 0
? minumum //use passed minimum if needed
: dict.Keys.Min(); //use real minimum
int max = dict.Count > 1
? dict.Keys.Max() + 2 //two steps away from maximum, avoids exceptions
: min + 2; //emulate data presence
return Enumerable.Range(min, max).Except(dict.Keys).First();
}
public static int? FirstFree(Dictionary<int, Guid> dict, int min, int max)
{
if (max <= min)
throw new Exception($"Specified range is invalid (must be max > min)");
if (max - min + 1 == dict.Count)
//no space left
return null;
return Enumerable.Range(min, max).Except(dict.Keys).First();
}
public static int FirstFree(Dictionary<int, Guid> dict, int min, int max)
{
if (max <= min)
throw new Exception($"Specified range is invalid (must be max > min)");
if (max - min + 1 == dict.Count)
//no space left
return int.MinValue;
return Enumerable.Range(min, max).Except(dict.Keys).First();
}