none
資料分析排序 RRS feed

  • 問題

  • 小弟最近有點迷糊了  想請教一個資料排序問題

    底下是資料格式

    日期_等級_教練

    1021001_初_AAA

    1021001_中_BBB

    1021002_初_AAA

    1021002_初_CCC

    1021002_高_DDD

    1021003_中_BBB

    1021003_高_DDD

    最後想呈現的表格樣式,可以指點一下 要怎麼做比較好的資料排序

    1021001

    1020102

    1021003

    初AAA

    初AAA

    初CCC

    中BBB

    中BBB

    高DDD

    高DDD

    2013年10月2日 上午 02:54

解答

  • 您好,
    使用Linq可以將資料依日期Group,您可以試看看能否再調整到您所需要的,如下,

    List<string> orgData = new List<string>();
                orgData.Add("1021001_初_AAA");
                orgData.Add("1021001_中_BBB");
                orgData.Add("1021002_初_AAA");
                orgData.Add("1021002_初_CCC");
                orgData.Add("1021002_高_DDD");
                orgData.Add("1021003_中_BBB");
                orgData.Add("1021003_高_DDD");
    
                var procDataArray = from oitem in orgData
                               select oitem.Split(new string[]{"_"},  StringSplitOptions.RemoveEmptyEntries);
                var procItems = from item in procDataArray
                                select new { c= item[0], lv= item[1], t= item[2]};
    
                var groupData = from item in procItems
                                group item by item.c
                                    into g
                                    select new
                                    {
                                        id = g.Key,
                                        gdata = g
                                    };


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已標示為解答 dodolon 2013年10月3日 上午 10:26
    2013年10月2日 上午 05:56
  • c.id   c.gdata.id  的方式在迴圈中取出


    • 已編輯 Mark Shu 2013年10月3日 上午 04:12
    • 已標示為解答 dodolon 2013年10月3日 上午 10:26
    2013年10月3日 上午 04:07
  • 您好,

    您可以透過2個foreach來取出資料,如下,

    List<string> orgData = new List<string>();
    orgData.Add("1021001_初_AAA");
    orgData.Add("1021001_中_BBB");
    orgData.Add("1021002_初_AAA");
    orgData.Add("1021002_初_CCC");
    orgData.Add("1021002_高_DDD");
    orgData.Add("1021003_中_BBB");
    orgData.Add("1021003_高_DDD");
    
    var procDataArray = from oitem in orgData
    					select oitem.Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries);
    var procItems = from item in procDataArray
    				select new { c = item[0], lv = item[1], t = item[2] };
    
    var groupData = from item in procItems
    				group item by item.c
    					into g
    					select new
    					{
    						id = g.Key,
    						gdata = g
    					};
    foreach (var item in groupData)
    {
    	foreach (var detail in item.gdata)
    	{
    		Console.WriteLine("id={0}, c={1}, lv={2}, t={3}", item.id, detail.c, detail.lv, detail.t);
    	}
    }

    而groupData中的就是依日期去Group,item.gdata就是某個日期的資料,output的資料如下,

    id=1021001, c=1021001, lv=初, t=AAA
    id=1021001, c=1021001, lv=中, t=BBB
    id=1021002, c=1021002, lv=初, t=AAA
    id=1021002, c=1021002, lv=初, t=CCC
    id=1021002, c=1021002, lv=高, t=DDD
    id=1021003, c=1021003, lv=中, t=BBB
    id=1021003, c=1021003, lv=高, t=DDD


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已提議為解答 LOLOTAModerator 2013年10月3日 上午 07:54
    • 已標示為解答 dodolon 2013年10月3日 上午 10:26
    2013年10月3日 上午 04:44

所有回覆

  • 可能 沒表達清楚

    資料格式非DB內資料格式,是經過擷取後放置在List<>

    想呈現的表格中 初中高 是想表達 一天當中 初中高 最多會有兩教練

    所以表格內只會有教練名稱 不會有初中高的顯示(如下圖)

    1021001

    1020102

    1021003

    AAA

    AAA



    CCC


    BBB


    BBB





    DDD

    DDD





    我目前想到的方法是用大量的if else 去分析然後填格子,但覺得不是很好想請教有沒有比較好的做法

    2013年10月2日 上午 05:26
  • 您好,
    使用Linq可以將資料依日期Group,您可以試看看能否再調整到您所需要的,如下,

    List<string> orgData = new List<string>();
                orgData.Add("1021001_初_AAA");
                orgData.Add("1021001_中_BBB");
                orgData.Add("1021002_初_AAA");
                orgData.Add("1021002_初_CCC");
                orgData.Add("1021002_高_DDD");
                orgData.Add("1021003_中_BBB");
                orgData.Add("1021003_高_DDD");
    
                var procDataArray = from oitem in orgData
                               select oitem.Split(new string[]{"_"},  StringSplitOptions.RemoveEmptyEntries);
                var procItems = from item in procDataArray
                                select new { c= item[0], lv= item[1], t= item[2]};
    
                var groupData = from item in procItems
                                group item by item.c
                                    into g
                                    select new
                                    {
                                        id = g.Key,
                                        gdata = g
                                    };


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已標示為解答 dodolon 2013年10月3日 上午 10:26
    2013年10月2日 上午 05:56
  • 不好意思 可以請教一下嗎

    gdata的資料要怎麼擷取

    我用

     foreach (object c in groupData)
                {
                    Console.WriteLine(c.ToString());
                }

    去接資料但出現

    { id = 1021001, gdata = System.Linq.Lookup`2+Grouping[System.String,<>f__AnonymousType0`3[System.String,System.String,System.String]] }

    原本想嘗試著

    有沒有辦法xxx.id  或xxx.gdata的方式取得內容  但似乎沒有這樣的屬性可以用

    可以指點一下  LINQ不是很熟

    2013年10月3日 上午 03:58
  • c.id   c.gdata.id  的方式在迴圈中取出


    • 已編輯 Mark Shu 2013年10月3日 上午 04:12
    • 已標示為解答 dodolon 2013年10月3日 上午 10:26
    2013年10月3日 上午 04:07
  • 您好,

    您可以透過2個foreach來取出資料,如下,

    List<string> orgData = new List<string>();
    orgData.Add("1021001_初_AAA");
    orgData.Add("1021001_中_BBB");
    orgData.Add("1021002_初_AAA");
    orgData.Add("1021002_初_CCC");
    orgData.Add("1021002_高_DDD");
    orgData.Add("1021003_中_BBB");
    orgData.Add("1021003_高_DDD");
    
    var procDataArray = from oitem in orgData
    					select oitem.Split(new string[] { "_" }, StringSplitOptions.RemoveEmptyEntries);
    var procItems = from item in procDataArray
    				select new { c = item[0], lv = item[1], t = item[2] };
    
    var groupData = from item in procItems
    				group item by item.c
    					into g
    					select new
    					{
    						id = g.Key,
    						gdata = g
    					};
    foreach (var item in groupData)
    {
    	foreach (var detail in item.gdata)
    	{
    		Console.WriteLine("id={0}, c={1}, lv={2}, t={3}", item.id, detail.c, detail.lv, detail.t);
    	}
    }

    而groupData中的就是依日期去Group,item.gdata就是某個日期的資料,output的資料如下,

    id=1021001, c=1021001, lv=初, t=AAA
    id=1021001, c=1021001, lv=中, t=BBB
    id=1021002, c=1021002, lv=初, t=AAA
    id=1021002, c=1021002, lv=初, t=CCC
    id=1021002, c=1021002, lv=高, t=DDD
    id=1021003, c=1021003, lv=中, t=BBB
    id=1021003, c=1021003, lv=高, t=DDD


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已提議為解答 LOLOTAModerator 2013年10月3日 上午 07:54
    • 已標示為解答 dodolon 2013年10月3日 上午 10:26
    2013年10月3日 上午 04:44
  • 了解了  原來沒注意到要用var型態來接收 

    我把型態設定錯誤難怪想說怎麼沒有屬性可以點出來

    感謝兩位的指教

    2013年10月3日 上午 05:22
  • 不好意思 請教一個延伸問題

    假設欄位格式是固定的

    1021001

    1020102

    1021003

    AAA

    AAA



    CCC


    BBB


    BBB





    DDD

    DDD




    如上述問題,這樣結果目前我用大量的判斷將結果填入式當的位置

    但我突然想到

    若我原始的資料若能將他照格式排序好是否會更好處理

    例如我接收到的資訊為

    日期_等級_教練

    1021001_初_AAA

    1021001_中_BBB

    1021002_初_AAA

    1021002_初_CCC

    1021002_高_DDD

    1021003_中_BBB

    1021003_高_DDD

    但我可以重新排列將空格填補起來

    例如

    日期_等級_教練

    1021001_初_AAA

    string.empty

    1021001_中_BBB

    string.empty

    string.empty

    string.empty

    1021002_初_AAA

    1021002_初_CCC

    string.empty

    ....依此類推

    這樣我可以快速將資料放置指定的位置內

    請教一下這樣該如何去做,效率上是否會比較好
    • 已編輯 dodolon 2013年10月10日 下午 05:11
    2013年10月10日 下午 05:09
  • 您好,
    請問同個日期、等級最多只會有2個教練嗎?
    您的資料是來源資料就是 日期_等級_教練 這樣子嗎?
    如果直接在SQL Server中處理,或許可以比較方便哦!
    請參考以下的SQL,

    --假設原本就是一個字串
    CREATE TABLE #t1
    (
    [ALL_IN] VARCHAR(30)
    );
    
    INSERT INTO #t1( ALL_IN ) VALUES  ('1021001_初_AAA');
    INSERT INTO #t1( ALL_IN ) VALUES  ('1021001_中_BBB');
    INSERT INTO #t1( ALL_IN ) VALUES  ('1021002_初_AAA');
    INSERT INTO #t1( ALL_IN ) VALUES  ('1021002_初_CCC');
    INSERT INTO #t1( ALL_IN ) VALUES  ('1021002_高_DDD');
    INSERT INTO #t1( ALL_IN ) VALUES  ('1021003_中_BBB');
    INSERT INTO #t1( ALL_IN ) VALUES  ('1021003_高_DDD');
    
    SELECT * FROM #t1
    
    --1.使用CTE將ALL_IN切成日期、等級、教練
    --2.使用Pivot + Union 將資料組合出來
    WITH Disp
    AS 
    (
    SELECT LEFT(ALL_IN, 7) AS [日期],
    SUBSTRING(ALL_IN, 9, 1) AS [等級],
    SUBSTRING(ALL_IN, 11, LEN(ALL_IN) - 10) AS [教練]
    FROM #t1)
    SELECT *
    FROM (SELECT [日期], [等級], [教練]
                FROM Disp
            ) AS P
            PIVOT 
            (   MAX([教練]) 
                FOR [日期] in ([1021001], [1021002], [1021003])
    		) maxOne
    UNION
    SELECT *
    FROM (SELECT [日期], [等級], [教練]
                FROM Disp
            ) AS P
            PIVOT 
            (   MIN([教練]) 
                FOR [日期] in ([1021001], [1021002], [1021003])
    		) minOne


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2013年10月11日 上午 02:12