简体   繁体   English

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

[英]Clearing a List<string> removes all values from Dictionary List of Strings, C#

Trying to read a csv file, and take the first word in the stream, throw it in to a dictionary while the following words get added to a list in that dictionary. 尝试读取一个csv文件,并将流中的第一个单词放入字典中,然后将随后的单词添加到该字典中的列表中。

However, I find that (during debugging) when, inside my loop I decide to clear my list, all of the values it had added to the dictionary previously also get cleared. 但是,我发现(在调试过程中)当我决定在循环中清除列表时,先前添加到字典中的所有值也都被清除了。 I guess I am mistaken in assuming it makes a copy of the list, it is actually just referencing that same list? 我猜我以为它是列表的副本是错误的,它实际上只是在引用相同的列表? Should I be creating a new list with every iteration? 我应该在每次迭代时创建一个新列表吗? Code below: 代码如下:

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);

    }
  }
}

The bottom foreach loop is just so I can see the results. 最下面的foreach循环就是这样,我可以看到结果。 Also, any critique is welcome in regards to how this is written, as I'm a beginner. 另外,我是初学者,欢迎就其写作方式提出任何批评。

Yes, you're adding the same object to your dictionary. 是的,您要将同一对象添加到字典中。

You can just change : 您可以更改:

theDatabase.Add(word, theList);

To : 至 :

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

Method ToList() makes shallow copy of your List<T> 方法ToList()对您的List<T>进行浅表复制

C# is pass by reference. C#通过引用传递。
So, theList and the list in your Dictionary are the same object. 因此, theListDictionary中的列表是同一对象。

The simplest solution is to stop clearing your List and create a new one every time instead: 最简单的解决方案是停止清除List ,而是每次都创建一个新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
}

It is more readable and clear solution: create a list, insert items, paste a list into the dictionary, continue the iteration. 它是一种更具可读性和清晰的解决方案:创建列表,插入项目,将列表粘贴到字典中,继续迭代。
It is also much more performant since there is no List clearing - List<T>.Clear() is a linear operation, which takes O(n) operations. 由于没有List清除,因此它的性能也更高List<T>.Clear()是线性运算,需要O(n)运算。

Yes, as everyone says, lists are reference types. 是的,正如大家所说,列表是引用类型。 You need to make a copy to avoid the .Clear() clearing all the lists. 您需要进行复制以避免.Clear()清除所有列表。

You could always write your code like this: 您总是可以这样编写代码:

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 */
}

} }

This doesn't have the problem with the list references. 列表引用没有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C#从字典获取值 <string, List<object> &gt; - C# getting values from Dictionary<string, List<object>> C#字典如何从带有单个键的重复值的分隔字符串列表中添加数据到字典 - c# dictionary how to add data from a delimited list of strings with repeated values for a single keyinto a dictionary 在C#中从字典获取列表的列表值 - Get list values of list from dictionary in C# 将 PowerShell 参数从字典更改为 C# 方法中的字符串列表 - Change PowerShell parameters from dictionary to list of strings in C# method C# 如何打印列表中的所有元素<dictionary<string,string> > 在控制台上? </dictionary<string,string> - C# How can I print all elements from List<Dictionary<string,string>> on the console? 从列表中检索值 <T> 属性并转换为字典 <string,string> C# - Retrieve values from List<T> property and cast to Dictionary<string,string> C# 在C#中的字符串列表中转换字典 - Convert Dictionary in List of of strings in C# 如何从C#中的字典和对象中获取所有字符串值 - how to get all of string values from dictionary and object in C# 从字典中选择值作为字符串列表 - Select Values from Dictionary as List of Strings 如何从字典中收集所有键的值 <string,object> 在清单中 - How to collect values for all the keys from a Dictionary<string,object> in a List
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM