将一行从CSV拆分为List <key,value =“”> </key,>

时间:2014-04-12 11:49:03

标签: c# linq

我有一个代表CSV的文本文件,带有';'是一个分隔符。这是一个虚拟转储供参考:

USER_EMPLOYEE_ID;SYSTEM1;USERNAME1;SYSTEM2;USERNAME2;SYSTEM3;USERNAME3;SYSTEM4;USERNAME4;SYSTEM5;USERNAME5;SYSTEM6;USERNAME6;SYSTEM7;USERNAME7;SYSTEM8;USERNAME8;SYSTEM9;USERNAME9;SYSTEM10;USERNAME10;SYSTEM11;USERNAME11;SYSTEM12;USERNAME12;SYSTEM13;USERNAME13;SYSTEM14;USERNAME14;SYSTEM15;USERNAME15;SYSTEM16;USERNAME16;SYSTEM17;USERNAME17;SYSTEM18;USERNAME18;SYSTEM19;USERNAME19;SYSTEM20;USERNAME20;SYSTEM21;USERNAME21;SYSTEM22;USERNAME22;SYSTEM23;USERNAME23;SYSTEM24;USERNAME24;SYSTEM25;USERNAME25;SYSTEM26;USERNAME26;SYSTEM27;USERNAME27;SYSTEM28;USERNAME28;SYSTEM29;USERNAME29;SYSTEM30;USERNAME30;SYSTEM31;USERNAME31;SYSTEM32;USERNAME32;SYSTEM33;USERNAME33;SYSTEM34;USERNAME34;SYSTEM35;USERNAME35;SYSTEM36;USERNAME36;SYSTEM37;USERNAME37;SYSTEM38;USERNAME38;SYSTEM39;USERNAME39;SYSTEM40;USERNAME40;SYSTEM41;USERNAME41;SYSTEM42;USERNAME42;SYSTEM43;USERNAME43;SYSTEM44;USERNAME44;SYSTEM45;USERNAME45;SYSTEM46;USERNAME46;SYSTEM47;USERNAME47;SYSTEM48;USERNAME48;SYSTEM49;USERNAME49;SYSTEM50;USERNAME50;SYSTEM51;USERNAME51;SYSTEM52;USERNAME52;SYSTEM53;USERNAME53;SYSTEM54;USERNAME54;SYSTEM55;USERNAME55;SYSTEM56;USERNAME56;SYSTEM57;USERNAME57;SYSTEM58;USERNAME58;SYSTEM59;USERNAME59;SYSTEM60;USERNAME60;SYSTEM61;USERNAME61;SYSTEM62;USERNAME62;SYSTEM63;USERNAME63;SYSTEM64;USERNAME64;SYSTEM65;USERNAME65;SYSTEM66;USERNAME66;SYSTEM67;USERNAME67;SYSTEM68;USERNAME68;SYSTEM69;USERNAME69;SYSTEM70;USERNAME70;SYSTEM71;USERNAME71;SYSTEM72;USERNAME72;SYSTEM73;USERNAME73;SYSTEM74;USERNAME74;SYSTEM75;USERNAME75;SYSTEM76;USERNAME76;SYSTEM77;USERNAME77;SYSTEM78;USERNAME78;SYSTEM79;USERNAME79;SYSTEM80;USERNAME80;SYSTEM81;USERNAME81;SYSTEM82;USERNAME82;SYSTEM83;USERNAME83;SYSTEM84;USERNAME84;SYSTEM85;USERNAME85;SYSTEM86;USERNAME86;SYSTEM87;USERNAME87;SYSTEM88;USERNAME88;SYSTEM89;USERNAME89;SYSTEM90;USERNAME90;SYSTEM91;USERNAME91;SYSTEM92;USERNAME92;SYSTEM93;USERNAME93;SYSTEM94;USERNAME94;SYSTEM95;USERNAME95;SYSTEM96;USERNAME96;SYSTEM97;USERNAME97;SYSTEM98;USERNAME98;SYSTEM99;USERNAME99;SYSTEM100;USERNAME100;SYSTEM101;USERNAME101;SYSTEM102;USERNAME102;SYSTEM103;USERNAME103;SYSTEM104;USERNAME104;SYSTEM105;USERNAME105;SYSTEM106;USERNAME106;SYSTEM107;USERNAME107;SYSTEM108;USERNAME108;SYSTEM109;USERNAME109;SYSTEM110;USERNAME110;SYSTEM111;USERNAME111;SYSTEM112;USERNAME112;SYSTEM113;USERNAME113;SYSTEM114;USERNAME114;SYSTEM115;USERNAME115;SYSTEM116;USERNAME116;SYSTEM117;USERNAME117;SYSTEM118;USERNAME118;SYSTEM119;USERNAME119;SYSTEM120;USERNAME120;SYSTEM121;USERNAME121;SYSTEM122;USERNAME122;SYSTEM123;USERNAME123;SYSTEM124;USERNAME124;SYSTEM125;USERNAME125;SYSTEM126;USERNAME126;SYSTEM127;USERNAME127
DGE3BLU;FS01;DGE3BLU;XHK218;DGE3BLU;XHP218;DGE3BLU;F3T103;DGE3BLU;FBP112;DGE3BLU;FBP112-1;DGE3BLU;F3D103;DGE3BLU;FSP100;DGE3BLU;FSP100-1;DGE3BLU;F3W103;DGE3BLU;FAT111;DGE3BLU;F3I103;DGE3BLU;FAK111;DGE3BLU;FAK111-1;DGE3BLU;FAK111-2;DGE3BLU;F3P103;DGE3BLU;F3P103-1;DGE3BLU;XHE218;DGE3BLU;FAW111;DGE3BLU;FAP111;DGE3BLU;FAP111-1;DGE3BLU;FAP111-2;DGE3BLU;F3K103;DGE3BLU;FKP111;DGE3BLU;FTP021;DGE3BLU;FAT113;DGE3BLU;F1P101;DGE3BLU;F1P101-1;DGE3BLU;FAT121;DGE3BLU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DGE3BMR;FS01;DGE3BMR;F3P103;DGE3BMR;F3P103-1;DGE3BMR;F1P101;DGE3BMR;F1P101-1;DGE3BMR;FSP100;DGE3BMR;FSP100-1;DGE3BMR;FBK112;DGE3BMR;FBK112-1;DGE3BMR;FAP111;DGE3BMR;FAP111-1;DGE3BMR;FAP111-2;DGE3BMR;FBT112;DGE3BMR;FBP112;DGE3BMR;FBP112-1;DGE3BMR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DGE3BOL;FS01;DGE3BOL;FAT111;DGE3BOL;FSQ100;DGE3BOL;FHI400;DGE3BOL;FSE100;DGE3BOL;F3K103;DGE3BOL;F1P101;DGE3BOL;F1P101-1;DGE3BOL;FHK222;DGE3BOL;FJI120;DGE3BOL;XHP218;DGE3BOL;F6P106;DGE3BOL;F3P103;DGE3BOL;F3P103-1;DGE3BOL;F1Q101;DGE3BOL;FTP021;DGE3BOL;F1K101;DGE3BOL;F1K101-1;DGE3BOL;FHE400;DGE3BOL;FAK111;DGE3BOL;FAK111-1;DGE3BOL;FAK111-2;DGE3BOL;FHP400;DGE3BOL;FSI100;DGE3BOL;FHE222;DGE3BOL;FSK100;DGE3BOL;FSK100-1;DGE3BOL;FAP111;DGE3BOL;FAP111-1;DGE3BOL;FAP111-2;DGE3BOL;FHI222;DGE3BOL;FSP100;DGE3BOL;FSP100-1;DGE3BOL;FHK400;DGE3BOL;FSD100;DGE3BOL;F6K106;DGE3BOL;FBP112;DGE3BOL;FBP112-1;DGE3BOL;FJK120;DGE3BOL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DGE3BOR;FS01;DGE3BOR;FSP100;DGE3BOR;FSP100-1;DGE3BOR;F6K106;DGE3BOR;FHP222;DGE3BOR;F3P103;DGE3BOR;F3P103-1;DGE3BOR;F4P104;DGE3BOR;F3T103;DGE3BOR;F4D604;DGE3BOR;FAP111;DGE3BOR;FAP111-1;DGE3BOR;FAP111-2;DGE3BOR;F6P106;DGE3BOR;FNK112;DGE3BOR;F3I103;DGE3BOR;FBK112;DGE3BOR;FBK112-1;DGE3BOR;F3D103;DGE3BOR;F3W103;DGE3BOR;FAE111;DGE3BOR;FAE111-1;DGE3BOR;FAE111-2;DGE3BOR;FPP126;DGE3BOR;F1K101;DGE3BOR;F1K101-1;DGE3BOR;FSI100;DGE3BOR;F7E107;DGE3BOR;F1Q101;DGE3BOR;F1P101;DGE3BOR;F1P101-1;DGE3BOR;FBE112;DGE3BOR;FBE112-1;DGE3BOR;F1F101;DGE3BOR;FSQ100;DGE3BOR;F5P105;DGE3BOR;FBP112;DGE3BOR;FBP112-1;DGE3BOR;F6E106;DGE3BOR;FJP120;DGE3BOR;F4K104;DGE3BOR;FBT112;DGE3BOR;F1F201;DGE3BOR;FHK222;DGE3BOR;FSK100;DGE3BOR;FSK100-1;DGE3BOR;F1W201;DGE3BOR;F3K103;DGE3BOR;F7T107;DGE3BOR;F6D106;DGE3BOR;FPK126;DGE3BOR;F7K107;DGE3BOR;F1W101;DGE3BOR;F4D104;DGE3BOR;FSD100;DGE3BOR;FHI222;DGE3BOR;FNP112;DGE3BOR;FSE100;DGE3BOR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

现在,第一列是用户标识符。对于这里的每个用户ID,我想生成一个跟随所有SYSTEMn和USERNAMEn的KeyValue对的列表。

我已经阅读了如下文件:

  using (var fs = File.Open(importFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
  {
    using (var bs = new BufferedStream(fs))
    {
      using (var sr = new StreamReader(bs))
      {
        String readLine;
        while ((readLine = sr.ReadLine()) != null)
        {
          if (String.IsNullOrEmpty(readLine) || readLine == "---EOF---")
          {
            break;
          }

          // Data line
          var dataRow = readLine.Split(new[] { ";" }, StringSplitOptions.None);

          // Skip the first element as it the identifier.
          var rights = dataRow.Skip(1).Select(new {Key=?, Value=?}).ToList();

        }
      }
    }
  }

哪种方式不起作用。有人可以提出解决方案吗?

感谢。

4 个答案:

答案 0 :(得分:1)

这为USER EMPLOYEE ID提供了密钥对值列表。

var DataArray = System.IO.File.ReadAllLines(FilePath, Encoding.Default).Select(x => x.Split(';').ToArray()).ToArray();

var ResultList = new List<Tuple<string, List<KeyValuePair<string, string>>>>();

foreach (var Line in DataArray.Skip((1))) // Skip Header
{
    String USER_EMPLOYEE_ID = Line[0];
    var KVpairs = new List<KeyValuePair<string, string>>();


    for (int i = 1; i < Line.Length; i += 2)
    {
        if (i + 1 < Line.Length)
            KVpairs.Add(new KeyValuePair<string, string>(Line[i], Line[i + 1]));
    }

    ResultList.Add(Tuple.Create(USER_EMPLOYEE_ID, KVpairs));
}

答案 1 :(得分:1)

通过LINQ做到这一点的好方法:

        List<string> data = new List(string);
        using (var fs = File.Open(importFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (var bs = new BufferedStream(fs))
            {
                using (var sr = new StreamReader(bs))
                {
                    String readLine;
                    while ((readLine = sr.ReadLine()) != null)
                    {
                        if (String.IsNullOrEmpty(readLine) || readLine == "---EOF---")
                        {
                            break;
                        }

                        data.Add(readLine);
                    }
                }
            }
        }

        var rights =
            data.Select(row => row.Split(new[] { ";" }, StringSplitOptions.None))
                .SelectMany(GetData).ToList();

创建一个私有静态方法来从每一行获取数据:

    private static IEnumerable<KeyValuePair<string, string>> GetData(string[] x)
    {
        for (int i = 1; i < x.Length; i += 2)
        {
            if (!String.IsNullOrEmpty(x[i]) && !String.IsNullOrEmpty(x[i + 1])) 
                yield return new KeyValuePair<string, string>(x[i], x[i + 1]);
        }
    }

请注意,您不能将列表的类型设为匿名,因为您需要在此解决方案中使用私有方法。所以我把它转换成了KeyValuePair,它已经包含了Key和Value。

答案 2 :(得分:1)

这个怎么样

var lookup = dataRow.Skip(1)
    .Select((data, index) => new { lookup = index % 2, index = index, data = data})
    .ToLookup(d => d.lookup);

var rights = lookup[0].Join(lookup[1],
        system => system.index + 1,
        username => username.index,
        (system, username) => new
        {
            system = system.data,
            useraname = username.data
        })
        .Where(d => !string.IsNullOrEmpty(d.system))
        .ToDictionary(d => d.system, d => d.useraname);

答案 3 :(得分:0)

试试这个...

当你在跳过第一个元素后得到列表时......再拿两个列表,即1)系统2)用户名....

根据结果添加项目,如果它在奇数位置甚至......

例如:

if(num % 2 == 0)
{
 // add to system
}
else
{
// add to username
}

希望这会给你一条继续的道路......