सीएसवी फ़ाइल को पढ़ने की कोशिश करना, और स्ट्रीम में पहला शब्द लेना, इसे एक शब्दकोश में फेंक दें जबकि निम्नलिखित शब्द उस शब्दकोश में एक सूची में जुड़ जाते हैं।

हालाँकि, मुझे लगता है कि (डिबगिंग के दौरान) जब, मेरे लूप के अंदर मैं अपनी सूची को साफ़ करने का निर्णय लेता हूं, तो पहले से शब्दकोश में जोड़े गए सभी मान भी साफ़ हो जाते हैं। मुझे लगता है कि मुझे यह मानने में गलती हो गई है कि यह सूची की एक प्रतिलिपि बनाता है, यह वास्तव में केवल उसी सूची का संदर्भ दे रहा है? क्या मुझे हर पुनरावृत्ति के साथ एक नई सूची बनानी चाहिए? नीचे कोड:

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

    }
  }
}

नीचे की ओर लूप लूप है, इसलिए मैं परिणाम देख सकता हूं। इसके अलावा, किसी भी आलोचक का स्वागत है कि यह कैसे लिखा जाए, जैसा कि मैं एक शुरुआत कर रहा हूं।

2
WerdaFerk 24 नवम्बर 2015, 13:29

3 जवाब

सबसे बढ़िया उत्तर

हां, आप अपने शब्दकोश में वही वस्तु जोड़ रहे हैं।

आप बस बदल सकते हैं:

theDatabase.Add(word, theList);

सेवा :

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

विधि ToList() आपके List<T> की उथली प्रति बनाती है

2
Fabjan 24 नवम्बर 2015, 10:33

C # संदर्भ से गुजरता है।
तो, theList और आपके Dictionary सूची समान ऑब्जेक्ट हैं।

सबसे आसान उपाय यह है कि आप अपने 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) संचालन होता है।

2
Yeldar Kurmangaliyev 24 नवम्बर 2015, 10:35

हां, जैसा कि सभी कहते हैं, सूची संदर्भ प्रकार हैं। आपको सभी सूचियों को साफ़ करने के लिए .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 */
}

}

यह सूची संदर्भों के साथ समस्या नहीं है।

2
Enigmativity 24 नवम्बर 2015, 10:47