这可能是一个简单的问题,但我无法在任何地方找到答案!正如您所能说的那样,我对编码很新。
我目前正在开发一个项目,该项目使用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处的键(值)at mySL1的索引5。 由于我可能想要访问mySL2中的特定键或值,因此foreach循环不够用。
答案 0 :(得分:0)
好吧,我还不完全确定原始海报的内容是什么,但这是我的 最好猜测我到目前为止的信息:
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)
在索引SortedList
上获取i
的密钥。
您还可以使用GetByIndex(i)
获取该索引处的值。所有这些都可以在文档中找到,我建议您一直阅读它以查看是否有任何可以使用的内容。
我会保留这个答案,以防它可能对原版海报有用。
您可以使用foreach
循环将第二个列表的值作为KeyValuePairs获取:
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>
,因为如果您使用non-generic version,则在访问值时会获得更多类型安全检查。通过使用带有显式类型的通用版本,您可以避免显式转换类型,就像使用非泛型版本(its methods return type 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"];
如果可以,通常最佳做法是使用通用版本的集合。在大多数情况下,您应该避免使用非泛型集合,现在您可能只能在遗留代码中看到它们。
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
的使用是一个有很多争论历史的话题。