在字典中按值查找项目的索引<br />
如何做得更好?看起来太没效率了, //在字典中查找给定值的索引 。//-1如果没有找到。
public int getFirstIndexOf(string search,Dictionary mydict)。
{。
int I = 0;。
foreach(key value pairmydict中的项目)。
{。
如果(项,Value == search)。
{。
返回I;。
}。
i++;。
}。
return-1;。
}。
**** Hidden Message ***** 字典(即哈希表)不能保证维护有序的索引,并且“项目返回的顺序是不确定的。”
也许自定义列表是一个更好的容器?
我们需要更多信息,这个索引有什么用? 字典中项目的顺序并不重要,前提是它在创建后不会立即更改。实际上,在实践中,第三方工具返回的布局顺序很少与图形中布局的实际顺序匹配,除了 item 始终是“模型”。它只是一个选择工具,用于将布局手柄与布局名称配对。该项目要求存储每个布局唯一可识别但未附加到布局的 xRecord 数据,因此即使随后删除了布局,该数据也将始终可用。在实体句柄...每个布局都有一个独特的布局,并且大多是稳定的.除非用户阻止绘图或执行其他一些通常不会定期执行的操作。程序捕获每个布局的实体句柄(键)和名称(值),并使用该信息填充组合框。表单可以在没有特定布局的情况下作为选定项进行实例化,在这种情况下,它始终默认为“Model”,或者用户可以打开表单并传递布局名称(因为这是用户可以识别布局的唯一方法),这就是问题所在。combobox 数据源是一个字典其中键是布局句柄,值是布局名称。每次显示表单时,它都会动态创建,并且永远不会被修改。当用户传递布局名称时,在初始化期间,需要设置组合框的 SelectedIndex,以便可以在其余控件中填充正确的信息。现在,用户无法知道数据是在H3A或B94或任何手柄下键入的,但他们确实知道布局被称为“模型”或“填充证据v2 2021”或任何情况。由于布局名称是 Value 而不是 Key,因此开箱即用的任何内容都无法让我弄清楚“填充的证据 v2 2021”是索引 4,因此我必须迭代集合并找到第一个实例(布局名称也必须是唯一的,因此它实际上是唯一找到的)。处理表单后,字典会随之运行。除非更改了组合框 SelectedItem,否则永远不会再次使用该索引。private void Form_Load()。
{。
_loading = 真;。
尝试。
{。
外部库布局帮助程序。
LayoutHelper helper = new LayoutHelper();。
string caption = helper.getDWGName(FilenameStyle.Elipsed);。
Dictionary cs = helper.getLayouts().ToDictionary();。
//将布局信息绑定到组合框。
cbxLayouts.ComboBox.DataSource = new BindingSource(cs, null);。
cbxLayouts.ComboBox.DisplayMember = “Value”;。
cbxLayouts.ComboBox.ValueMember = “Key”;。
//_initialLayout是“Model”,或者如果未找到匹配的布局,则返回构造函数 -1 中传递的字符串 。
cbxLayouts.SelectedIndex = getFirstIndexOf(_initialLayout, cs);。
if (cbxLayouts.Text != “”)。
{。
获取具有匹配的布局句柄(主)或名称(辅助)的 xRecords。
_data = helper.getXrecords(((KeyValuePair)cbxLayouts.SelectedItem()).Key, ((KeyValuePair)cbxLayouts.SelectedItem()).值);。
}。
}。
catch{}。
_loading = 假;。
}。
。
private void cbxLayouts_SelectedIndexChanged(object sender, EventArgs e)。
{。
如果 (!_loading)。
{。
尝试。
{。
_data = helper.getXrecords(((KeyValuePair)cbxLayouts.SelectedItem()).Key, ((KeyValuePair)cbxLayouts.SelectedItem()).值);。
}。
catch{}。
}。
}。
。
在字典中查找给定值的索引。
//-1(如果未找到)。
public int getFirstIndexOf(字符串搜索, Dictionary mydict)。
{。
整型 i = 0;。
foreach (KeyValuePair item in mydict)。
{。
如果 (项目,值 == 搜索)。
{。
返回 i;。
}。
i++;。
}。
返回 -1;。
}这本身可能不是处理任务的最佳方式,但它是我必须处理的,如果我可以告诉函数以不同的方式返回数据(比如交换值和键),我可以使键显示为显示成员,然后使用OOB函数获取布局句柄的Value成员。
将字典迭代到列表以获取布局名称以填充组合框,然后您可以获取选定的组合框“值”并使用它通过使用ContainsValue/ContainsKey或类似方式搜索原始字典,怎么样? 我不确定这会对我有什么帮助。我仍然需要迭代一些东西,无论是字典还是组合框值。迭代字典并填充组合框只能确保我需要再次迭代列表,现在我可以迭代字典并将_initallyout与item进行比较。值并获取索引,但不管怎样,我仍在迭代字典,坦率地说,我看不到字典改变顺序的速度有多快,因为IndexOf(key)也没用。
返回mydict。选择((d,i)=>new{d.Value,Index=i})
.FirstOrDefault(e=>e.Value==search)?。指数-1;
这是一个完美的例子,说明WPF和MVVM模式如何优于其他任何东西。NET UI。您将拥有字典
作为ViewModel的属性,它将绑定到ComboBox,并且您不必编写任何代码来迭代字典。
Keith我知道您的项目为时已晚,但如果其他人现在正在阅读此线程,那将是一个很好的时机,让他们远离过时的表单并让他们朝着正确的方向前进。 Keith,您似乎正在处理布局(布局id存储在LayoutDictionary中的顺序与实际的Latout Tab顺序)。正如Mike D指出的,“字典不能保证维护有序的索引”。这就是为什么布局类有一个属性“TabOrder”。因此,如果您需要您的UI以与布局选项卡顺序相同的顺序呈现布局信息,仅处理LayoutDictionary是不够的,您还需要打开每个布局对象以获取其“tab order”属性。
我也同意MexicanCustard的观点:如果用户界面是无模式的,尤其是PaletteSet,只要有可能,利用WPF的绑定总是第一选择。 如果字典在将来的某个时候改变它的顺序并不重要。我只需要知道项目
在创建时*现在*在字典中的位置。因为字典正在填充组合框并且组合框中项目的顺序是无关紧要的。
每个人似乎都专注于字典可以改变其顺序的事实...这很好,但是如果有那么大的问题,按值搜索和获取索引与按键搜索和获取索引有什么本质上的不同?如果你认为它完全无关紧要。
考虑这个
字典在创建时是这样组织的:
ndx Value Key
0
1
2
如果我想知道位置1中的内容,我可以询问Item
如果我想知道Key 456的索引,我可以询问IndexOf(456),它会返回1
那么为什么从值即IndexOf(DEF)获取索引是错误的呢?IndexOf(456)不会也是错误的吗?
这会以更简洁的方式产生所需的结果。我会用的。谢谢!
只有当有一个“很多”条目
System.Collections.Specialized.OrderedDictionary 迭代时,请参阅函数 IndexOfKey
https://referencesource.microsoft.com/#system/compmod/system/collections/specialized/ordereddictionary.cs
,以便您可以滚动类似
class CoolDictionary : Dictionary
{
public int IndexOfKey(string key)
{
int nitem = 0;
foreach(var entry in this)
{
if (entry.Key == key)
return nitem;
nitem++;
}
return -1;
}
}
页:
[1]
2