访问排序列表,这是另一个排序列表的值
本文关键字:排序 列表 另一个 访问 | 更新日期: 2023-09-27 17:56:03
这可能是一个简单的问题,但我在任何地方都找不到答案!正如你所能知道的,我对编码相当陌生。
我目前正在从事一个项目,该项目使用SortedList
将字符串值存储为其键,将第二个SortedList
存储为其值。第二个SortedList
具有一系列数字 ID(尽管存储为字符串)作为键,另一个字符串作为值。
我输入上面的值没有问题,但是我在访问第二个 SortedList 时遇到问题,这是第一个的值。
我把自己打结,试图解决这个问题,希望有人能够为我指出正确的方向。
下面的示例(简化)代码...
//New and empty SortedLists created
SortedList mySL1 = new SortedList();
SortedList mySL2 = new SortedList();
//Clicking button1 first ensures mySL2 is clear and then adds a couple of KVPs
//Then text entered into a textBox and mySL2 are added as a KVP to mySL1
private void button1_Click(object sender, EventArgs e)
{
mySL2.Clear();
mySL2.Add("w", "x");
mySL2.Add("y", "z");
mySL1.Add(textBox1.Text, mySL2);
}
//Clicking button2 outputs each of the keys of mySL1 to a listBox
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i < mySL1.Count; i++)
{
listBox1.Items.Add(mySL1.GetKey(i));
}
}
private void button3_Click(object sender, EventArgs e)
{
for (int i = 0; i < mySL1.Count; i++)
{
//How do I access the KVPs of the mySL2 SortedLists which are the values of mySL1?
}
}
编辑
我怀疑我一直不清楚我在问什么,并且通过在我的"简单代码"中包含 for 循环来使一个相当简单的查询过于复杂。我遇到的问题是访问列表中列表的语法。
假设,如上例所示,我有一个排序列表 (mySL1),其中的值是第二个排序列表 (mySL2)。
在索引 5 处访问 mySL1 键的语法是 mySL1.GetKey(5)
我试图找出的是访问mySL1特定索引的mySL2中的特定键或值的语法,例如mySL2列表索引6处的键,该键(值)位于mySL1的索引5处。由于我可能想从 mySL2 访问特定的键或值,因此 foreach 循环是不够的。
新答案
好的,我仍然不完全确定原始海报在寻找什么,但这是我的最好猜测我目前掌握的信息:
private void button3_Click(object sender, EventArgs e)
{
for (int i = 0; i < listOfLists.Count; i++)
{
var list = (SortedList) listOfLists.GetByIndex(i);
for (int j = 0; j < list.Count; j++)
{
var key = (string) list.GetKey(j);
var value = (string) list.GetByIndex(j);
}
}
}
您已经知道如何使用 GetKey(i)
在索引i
获取SortedList
的密钥。您还可以使用 GetByIndex(i)
获取该索引处的值。所有这些都可以在文档中找到,我建议您始终阅读它以查看其中是否有可以使用的内容。
旧答案
我保留了这个答案,以防它对原始海报有用。
您可以使用foreach
循环将第二个列表的值作为键值对获取:
var lists = new SortedList<string, SortedList<string, string>>
{
{
"foo",
new SortedList<string, string>
{
{ "0", "lol" },
{ "1", "skadoosh!" },
{ "2", "OMG!" }
}
}
};
foreach (var list in lists)
{
foreach (var kvp in list.Value)
{
Console.WriteLine("({0}, {1})", kvp.Key, kvp.Value);
}
}
首选通用集合而不是非通用集合
因此,上面需要注意几点。我使用的是SortedList
的通用版本,即 SortedList<TKey, TValue>
,因为在访问值时,您比使用非泛型版本时获得更多的类型安全检查。通过使用带有显式类型的泛型版本,可以避免像使用非泛型版本(其方法返回类型object
)那样显式强制转换类型,如下所示:
var list = new SortedList();
list["foo"] = "bar";
string x = (string) list["foo"];
// vs generic
var list = new SortedList<string, string>();
list["foo"] = "bar";
string x = list["foo"];
如果可以,通常最佳做法是使用集合的通用版本。在大多数情况下,您应该避免使用非泛型集合,现在您可能只会在遗留代码中看到它们。
foreach 循环与SortedList<TKey, TValue>
好的,因此foreach
循环允许您获取集合的值,而无需指定索引或键。那么SortedList<TKey, TValue>
的价值是什么?这些值KeyValuePair<TKey, TValue>
:
SortedList<string, SortedList<string, string>>
包含KeyValuePair<string, SortedList<string, string>>
.SortedList<string, string>
包含KeyValuePair<string, string>
.
因此,在第一个foreach
循环中,您得到KeyValuePair<string, SortedList<string, string>>
,并且您想要访问该对中的值的列表:
foreach (var list in lists)
{
foreach (var kvp in list.Value)
{
// Do stuff with kvp
}
}
所以list.Value
是一个SortedList<string, string>
,它包含(key, value)
对更多的字符串。因此,您可以使用 kvp.Key
和 kvp.Value
访问每个键和值。
var
还是不var
?这就是问题所在:P
您还可以通过显式指定项目类型来声明 foreach
循环,而不是使用 var
:
foreach (KeyValuePair<string, SortedList<string, string>> list in lists)
{
foreach (KeyValuePair<string, string> kvp in list.Value)
{
Console.WriteLine("({0}, {1})", kvp.Key, kvp.Value);
}
}
你选择哪种风格取决于你,它们都是等效的。就个人而言,我只在类型明显时才使用var
,否则很难判断正在使用哪种类型,特别是如果您正在查看Visual Studio之外的代码,例如在Git diff或其他东西中。使用 var
而不是显式类型的另一个缺点是,您无法使用接口声明对象实例,如下所示:
IDictionary<int, string> players = new SortedList<int, string>
{
{ 0, "John" }, { 1, "Dave" }
};
使用接口声明对象实例意味着将强制您仅使用该接口声明的方法,这样可以使您以后更轻松地切换实现。当然,这要不那么冗长:
var players = new SortedList<int, string> { { 0, "John" }, { 1, "Dave" } };
var
的使用是一个