清除列表<;字符串>;从字符串字典列表C#中删除所有值

本文关键字:字符串 列表 删除 lt gt 清除 字典 | 更新日期: 2023-09-27 18:24:08

试图读取csv文件,并获取流中的第一个单词,将其放入词典,同时将以下单词添加到该词典的列表中。

然而,我发现(在调试过程中)当我在循环中决定清除列表时,它之前添加到字典中的所有值也会被清除。我想我错了,假设它是列表的副本,它实际上只是引用了同一个列表?我应该为每次迭代创建一个新列表吗?以下代码:

public class TestScript : MonoBehaviour {
// Use this for initialization
void Start() {
    Dictionary<string, List<string>> theDatabase = new Dictionary<string, List<string>>();
    string word;
    string delimStr = ",.:";
    char[] delimiter = delimStr.ToCharArray();
    List<string> theList = new List<string>();

    using (StreamReader reader = new StreamReader("testComma.csv")) {
        while (true) {
            //Begin reading lines
            string line = reader.ReadLine();
            if (line == null) {
                break;
            }
            //Begin splitting lines, adding to array.
            string[] split2 = line.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
            //Loop to hold the first word in the stream
            for(int i = 0; i <= 0; i++) {
                word = split2[i];
                //loop to hold the following words in to list.
                for (int y = 1; y < split2.Length; y++) {
                    theList.Add(split2[y]);
                }
                //Add word/list combo in to the database
                theDatabase.Add(word, theList);
                //clear the list.
                theList.Clear();
            }
        }
    }
    foreach (KeyValuePair<string, List<string>> pair in theDatabase) {
        string keys;
        List<string> values;
        keys = pair.Key;
        values = pair.Value;
        print(keys + " = " + values);
    }
  }
}

底部的foreach循环只是为了让我可以看到结果。此外,任何关于这篇文章的写作方式的评论都是受欢迎的,因为我是一个初学者。

清除列表<;字符串>;从字符串字典列表C#中删除所有值

是的,您正在向字典中添加相同的对象。

您可以更改:

theDatabase.Add(word, theList);

收件人:

theDatabase.Add(word, theList.ToList());

方法ToList()List<T> 进行浅层复制

C#是通过引用传递的
因此,theListDictionary中的列表是同一个对象。

最简单的解决方案是停止清除List,每次都创建一个新的:

for(int i = 0; i <= 0; i++) {
    List<string> theList = new List<string>(); // it is in a loop now
    word = split2[i];
    //loop to hold the following words in to list.
    for (int y = 1; y < split2.Length; y++) {
        theList.Add(split2[y]);
    }
    //Add word/list combo in to the database
    theDatabase.Add(word, theList);
    //clear the list.
    //theList.Clear(); - not required anymore
}

它是一个可读性更强、更清晰的解决方案:创建一个列表,插入项目,将列表粘贴到字典中,继续迭代
由于没有List清除,它的性能也高得多——List<T>.Clear()是一个线性运算,需要O(n)运算。

是的,正如大家所说,列表是引用类型。您需要制作一个副本,以避免.Clear()清除所有列表。

你可以一直这样写你的代码:

void Start()
{
    string delimStr = ",.:";
    Dictionary<string, List<string>> theDatabase = 
        File
            .ReadAllLines("testComma.csv")
            .Select(line => line.Split(delimStr.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
            .ToDictionary(x => x[0], x => x.Skip(1).ToList());
    /* foreach here */
}

}

这对列表引用没有问题。