none
資料量大的時候又必須該逐一比對該如何 ? RRS feed

  • 問題

  • H E L L O !

    想要請各位來幫我探討作法上的問題,

    我目前遇到的情況是 :

    假設我的資料檔為 test.txt ,內容為下列

    name      nickName

    AAA          bob       
    AAB          joe
    AAC          chris
    AAA          big bob
    AAB          joe
    AAD          kay

    我把 txt 檔把資料一行一行的讀進來,

    轉變成 :

    AAA      bob
                big bob

    AAB      joe
    AAC      chris
    AAD      kay

    一方面必需去掉重複的,以及必須顧及一對多

    另一方面其實我手中的資料量大概是 5 萬筆

    想請問各位會怎麼做 ?

    我ㄧ開始是以後項去比對前項但很快就發現有錯,

    目前是想丟進陣列裡面逐一比對測試,

    在這邊想請問各位,各位有什麼好的作法,請給我ㄧ個方向 !

    謝謝!
    2009年12月23日 上午 11:25

解答

所有回覆

  • 最後結果要放進資料庫的話,那不如一開始就直接匯到資料庫去,再分割成兩張表


    或者試試看SortedDictionary類別,擷取、寫入跟移除都是 O(log n)

    SortedDictionary<string, List<string>> dictionary = new SortedDictionary<string, List<string>>();
    



    可以用ContainsKey()來做比對

    if (dictionary.ContainsKey("test"))
        dictionary["test"].Add("aaa");
    else
        dictionary.Add("test", new List<string>() { "aaa" });


    2009年12月23日 下午 12:40
  • Hi,

    可以使用NameValueCollection或是Linq

    NameValueCollection可參考

    NameValueCollection 類別

    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    • 已提議為解答 Shelly Chen 2009年12月24日 上午 08:10
    • 已標示為解答 EM8H 2009年12月27日 下午 01:04
    2009年12月23日 下午 12:42
  • 我是用Dictionary及StringCollection去做這個一對多的動作,跑了一下感覺還OK.
    重點是在第一個foreach裡面的if判斷.

    private void button1_Click(object sender, EventArgs e)
    {
    	NameValueCollection nvc = GetTempData();//取得測試來源資料
    
    	//過濾資料
    	Dictionary<string,StringCollection> dt=new Dictionary<string,StringCollection>();
    	StringCollection sc = new StringCollection();//暫存Value
    	foreach (string sKey in nvc.AllKeys)
    	{
    		foreach (string sVal in nvc.GetValues(sKey))
    		{
    			if (dt.ContainsKey(sKey))//如果有重覆的Key,再去判斷是否有重覆的Value
    			{
    				if (!dt[sKey].Contains(sVal))
    				{//沒有重覆的Value,再去新增
    					dt[sKey].Add(sVal);
    				}
    			}
    			else
    			{//新增一筆
    				sc.Add(sVal);
    				dt.Add(sKey, sc);
    				sc.Clear();
    			}
    		}
    	}
    
    	//顯示資料
    	richTextBox1.Text = string.Empty;
    	StringBuilder sb = new StringBuilder();
    	foreach (string sKey in dt.Keys)
    	{
    		sb.AppendFormat("Key : {0} ============\r\n", sKey);
    		foreach (string sVal in dt[sKey])
    		{
    			sb.AppendFormat("{0}\r\n", sVal);
    		}
    	}
    	richTextBox1.Text = sb.ToString();
    }
    
    //供測試用的來源資料
    private NameValueCollection GetTempData()
    {
    	NameValueCollection nvc = new NameValueCollection();
    	Random rnd=new Random(DateTime.Now.Millisecond);
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("a", rnd.Next(1000).ToString());    
    	}
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("b", rnd.Next(1000).ToString());
    	}
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("c", rnd.Next(1000).ToString());
    	}
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("d", rnd.Next(1000).ToString());
    	}
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("e", rnd.Next(1000).ToString());
    	}
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("f", rnd.Next(1000).ToString());
    	}
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("g", rnd.Next(1000).ToString());
    	}
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("h", rnd.Next(1000).ToString());
    	}
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("i", rnd.Next(1000).ToString());
    	}
    	for (int i = 0; i < 2000; i++)
    	{
    		nvc.Add("j", rnd.Next(1000).ToString());
    	}
    
    	return nvc;
    }
    2009年12月24日 上午 07:03
  • 其實用namevaluecollection比較省事,先把所有東西加進去之後,跑一個迴圈去掉重覆值就好。

    用其它的集合還要先判斷key存不存在....namevaluecollection直接全部進去,value自動幫你弄好陣列,超省事。
    My Blog:http://www.dotblogs.com.tw/alonstar
    解決問題之後,別忘了回到論壇把正確回應標示成解答哦!
    2009年12月24日 上午 08:10
  • 感謝各位的解答,這幾天比較忙沒辦法進行測試,

    星期六終於有時間實驗!!!!

    非常感謝各位熱心的解答! 謝謝!
    2009年12月27日 下午 01:03