سؤال

لدي تطبيق وحدة تحكم أساسي في C# يقرأ ملفًا نصيًا (تنسيق CSV) سطرًا تلو الآخر ويضع البيانات في HashTable.عنصر CSV الأول في السطر هو المفتاح (رقم المعرف) وبقية السطر هو القيمة.ومع ذلك فقد اكتشفت أن ملف الاستيراد الخاص بي يحتوي على عدد قليل من المفاتيح المكررة التي لا ينبغي أن تحتوي عليه.عندما أحاول استيراد الملف، تظهر أخطاء التطبيق لأنه لا يمكن أن يكون لديك مفاتيح مكررة في HashTable.أريد أن يكون برنامجي قادرًا على التعامل مع هذا الخطأ بالرغم من ذلك.عندما أواجه مفتاحًا مكررًا، أرغب في وضع هذا المفتاح في قائمة المصفوفات ومواصلة استيراد بقية البيانات إلى جدول التجزئة.كيف يمكنني القيام بذلك في C#

هنا هو الكود الخاص بي:


استيراد علامة التجزئة الثابتة الخاصة (hashtable myhashtable ، سلسلة myfilename) {

        StreamReader sr = new StreamReader(myFileName);
        CSVReader csvReader = new CSVReader();
        ArrayList tempArray = new ArrayList();
        int count = 0;

        while (!sr.EndOfStream)
        {
            String temp = sr.ReadLine();
            if (temp.StartsWith(" "))
            {
                ServMissing.Add(temp);
            }
            else
            {
                tempArray = csvReader.CSVParser(temp);
                Boolean first = true;
                String key = "";
                String value = "";

                foreach (String x in tempArray)
                {
                    if (first)
                    {
                        key = x;
                        first = false;
                    }
                    else
                    {
                        value += x + ",";
                    }
                }
                myHashtable.Add(key, value);
            }
            count++;
        }

        Console.WriteLine("Import Count: " + count);
        return myHashtable;
    }
هل كانت مفيدة؟

المحلول

if (myHashtable.ContainsKey(key))
    duplicates.Add(key);
else
    myHashtable.Add(key, value);

نصائح أخرى

الحل الأفضل هو استدعاء يحتوي على المفتاح للتحقق من وجود المفتاح قبل إضافته إلى جدول التجزئة بدلاً من ذلك.يعد طرح الاستثناء على هذا النوع من الأخطاء بمثابة نتيجة أداء ولا يؤدي إلى تحسين تدفق البرنامج.

يحتوي يحتوي على مفتاح O(1) ثابتًا لكل عنصر، بينما يؤدي الحصول على استثناء إلى تحقيق نتيجة أداء على العناصر المكررة فقط.

في معظم المواقف، أود أن أقول التحقق من وجود المفتاح، ولكن في هذه الحالة، من الأفضل اكتشاف الاستثناء.

فيما يلي حل يتجنب الزيارات المتعددة في القائمة الثانوية مع زيادة طفيفة في جميع عمليات الإدراج:

Dictionary<T, List<K>> dict = new Dictionary<T, List<K>>();

//Insert item
if (!dict.ContainsKey(key))
   dict[key] = new List<string>();
dict[key].Add(value);

يمكنك تغليف القاموس بنوع يخفي ذلك أو وضعه في طريقة أو حتى طريقة تمديد على القاموس.

إذا كان لديك أكثر من 4 قيم بتنسيق CSV (على سبيل المثال)، فقد يكون من المفيد تعيين قيمة متغير لاستخدام StringBuilder أيضًا نظرًا لأن تسلسل السلسلة هو وظيفة بطيئة.

حسنًا، 1.7 مليون سطر؟أتردد في تقديم هذا لهذا النوع من الحمل.

إليك إحدى الطرق للقيام بذلك باستخدام LINQ.

CSVReader csvReader = new CSVReader();
List<string> source = new List<string>();
using(StreamReader sr = new StreamReader(myFileName))
{
  while (!sr.EndOfStream)
  {
    source.Add(sr.ReadLine());
  }
}
List<string> ServMissing =
  source
  .Where(s => s.StartsWith(" ")
  .ToList();
//--------------------------------------------------
List<IGrouping<string, string>> groupedSource = 
(
  from s in source
  where !s.StartsWith(" ")
  let parsed = csvReader.CSVParser(s)
  where parsed.Any()
  let first = parsed.First()
  let rest = String.Join( "," , parsed.Skip(1).ToArray())
  select new {first, rest}
)
.GroupBy(x => x.first, x => x.rest)   //GroupBy(keySelector, elementSelector)
.ToList()
//--------------------------------------------------
List<string> myExtras = new List<string>();
foreach(IGrouping<string, string> g in groupedSource)
{
  myHashTable.Add(g.Key, g.First());
  if (g.Skip(1).Any())
  {
    myExtras.Add(g.Key);
  } 
}

شكرا لكم جميعا.انتهى بي الأمر باستخدام طريقة يحتوي على مفتاح ().ربما يستغرق الأمر 30 ثانية أطول، وهو أمر جيد لأغراضي.أقوم بتحميل حوالي 1.7 مليون سطر ويستغرق البرنامج حوالي 7 دقائق تقريبًا لتحميل ملفين ومقارنتهما وكتابة بعض الملفات.يستغرق الأمر حوالي ثانيتين فقط لإجراء المقارنة وكتابة الملفات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top