乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 173|回复: 10

在字典中按值查找项目的索引<br />

[复制链接]

154

主题

1274

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1936
发表于 2018-8-25 16:38:34 | 显示全部楼层 |阅读模式
如何做得更好?看起来太没效率了,   //在字典中查找给定值的索引 。
//-1如果没有找到。
public int getFirstIndexOf(string search,Dictionary mydict)。
{。
int I = 0;。
foreach(key value pair  mydict中的项目)。
{。
如果(项,Value == search)。
{。
返回I;。
}。
i++;。
}。
return-1;。
}。

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

69

主题

875

帖子

15

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1146
发表于 2018-8-25 21:59:02 | 显示全部楼层
字典(即哈希表)不能保证维护有序的索引,并且“项目返回的顺序是不确定的。”
也许自定义列表是一个更好的容器?
我们需要更多信息,这个索引有什么用?
回复

使用道具 举报

154

主题

1274

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1936
发表于 2018-8-26 00:52:32 | 显示全部楼层
字典中项目的顺序并不重要,前提是它在创建后不会立即更改。实际上,在实践中,第三方工具返回的布局顺序很少与图形中布局的实际顺序匹配,除了 item[0] 始终是“模型”。它只是一个选择工具,用于将布局手柄与布局名称配对。该项目要求存储每个布局唯一可识别但未附加到布局的 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成员。
回复

使用道具 举报

69

主题

875

帖子

15

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1146
发表于 2018-8-26 17:58:38 | 显示全部楼层
将字典迭代到列表以获取布局名称以填充组合框,然后您可以获取选定的组合框“值”并使用它通过使用ContainsValue/ContainsKey或类似方式搜索原始字典,怎么样?
回复

使用道具 举报

154

主题

1274

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1936
发表于 2018-8-26 18:32:37 | 显示全部楼层
我不确定这会对我有什么帮助。我仍然需要迭代一些东西,无论是字典还是组合框值。迭代字典并填充组合框只能确保我需要再次迭代列表,现在我可以迭代字典并将_initallyout与item进行比较。值并获取索引,但不管怎样,我仍在迭代字典,坦率地说,我看不到字典改变顺序的速度有多快,因为IndexOf(key)也没用。
回复

使用道具 举报

24

主题

204

帖子

6

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
300
发表于 2018-8-27 07:22:39 | 显示全部楼层
返回mydict。选择((d,i)=>new{d.Value,Index=i})
.FirstOrDefault(e=>e.Value==search)?。指数-1;

回复

使用道具 举报

24

主题

204

帖子

6

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
300
发表于 2018-8-27 07:30:58 | 显示全部楼层
这是一个完美的例子,说明WPF和MVVM模式如何优于其他任何东西。NET UI。您将拥有字典
作为ViewModel的属性,它将绑定到ComboBox,并且您不必编写任何代码来迭代字典。
Keith我知道您的项目为时已晚,但如果其他人现在正在阅读此线程,那将是一个很好的时机,让他们远离过时的表单并让他们朝着正确的方向前进。
回复

使用道具 举报

4

主题

219

帖子

4

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
238
发表于 2018-8-27 09:16:45 | 显示全部楼层
Keith,您似乎正在处理布局(布局id存储在LayoutDictionary中的顺序与实际的Latout Tab顺序)。正如Mike D指出的,“字典不能保证维护有序的索引”。这就是为什么布局类有一个属性“TabOrder”。因此,如果您需要您的UI以与布局选项卡顺序相同的顺序呈现布局信息,仅处理LayoutDictionary是不够的,您还需要打开每个布局对象以获取其“tab order”属性。
我也同意MexicanCustard的观点:如果用户界面是无模式的,尤其是PaletteSet,只要有可能,利用WPF的绑定总是第一选择。
回复

使用道具 举报

154

主题

1274

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1936
发表于 2018-8-27 15:48:48 | 显示全部楼层
如果字典在将来的某个时候改变它的顺序并不重要。我只需要知道项目
在创建时*现在*在字典中的位置。因为字典正在填充组合框并且组合框中项目的顺序是无关紧要的。
每个人似乎都专注于字典可以改变其顺序的事实...这很好,但是如果有那么大的问题,按值搜索和获取索引与按键搜索和获取索引有什么本质上的不同?如果你认为它完全无关紧要。
考虑这个
字典在创建时是这样组织的:
ndx Value Key
0
1
2
如果我想知道位置1中的内容,我可以询问Item[1]
如果我想知道Key 456的索引,我可以询问IndexOf(456),它会返回1
那么为什么从值即IndexOf(DEF)获取索引是错误的呢?IndexOf(456)不会也是错误的吗?
这会以更简洁的方式产生所需的结果。我会用的。谢谢!
回复

使用道具 举报

154

主题

1274

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1936
发表于 2018-8-29 10:43:40 | 显示全部楼层

只有当有一个“很多”条目
System.Collections.Specialized.OrderedDictionary 迭代时,请参阅函数 IndexOfKey
https://referencesource.microsoft.com/#system/compmod/system/collections/specialized/ordereddictionary.cs
,以便您可以滚动类似
  1. class CoolDictionary : Dictionary
  2.     {
  3.         public int IndexOfKey(string key)
  4.         {
  5.             int nitem = 0;
  6.             foreach(var entry in this)
  7.             {
  8.                 if (entry.Key == key)
  9.                     return nitem;
  10.                 nitem++;
  11.             }
  12.             return -1;
  13.         }
  14.    }

回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-2-4 08:49 , Processed in 0.235115 second(s), 72 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表