拆分字符串并连接所有第一个元素然后连接第二个元素,依此类推c#

时间:2017-09-08 09:27:06

标签: c# .net arrays linq

我有一个像这样的字符串 -

var roleDetails = "09A880C2-8732-408C-BA09-4AD6F0A65CE9^Z:WB:SELECT_DOWNLOAD:0000^Product Delivery - Download^1,24B11B23-1669-403F-A24D-74CE72DFD42A^Z:WB:TRAINING_SUBSCRIBER:0000^Training Subscriber^1,6A4A6543-DB9F-46F2-B3C9-62D69D28A0B6^Z:WB:LIC_MGR_HOME_REDL:0000^License Manager - Home use^1,76B3B165-0BB4-4E3E-B61F-0C0292342CE2^Account Admin^Account Admin^1,B3C0CE51-00EE-4A0A-B208-98653E21AE11^Z:WB:1BENTLEY_ISA_ADMIN:0000^Co-Administrator^1,CBA225BC-680C-4627-A4F6-BED401682816^ReadOnly^ReadOnly^1,D80CF5CF-CB6E-4424-9D8F-E29F96EBD4C9^Z:WB:MY_SELECT_CD:0000^Product Delivery - DVD^1,E0275936-FBBB-4775-97D3-9A7D19D3E1B4^Z:WB:LICENSE_MANAGER:0000^License Manager^1";

用“,”分隔它会返回 -

[0] "09A880C2-8732-408C-BA09-4AD6F0A65CE9^Z:WB:SELECT_DOWNLOAD:0000^Product Delivery - Download^1"
[1] "24B11B23-1669-403F-A24D-74CE72DFD42A^Z:WB:TRAINING_SUBSCRIBER:0000^Training Subscriber^1"
[2] "6A4A6543-DB9F-46F2-B3C9-62D69D28A0B6^Z:WB:LIC_MGR_HOME_REDL:0000^License Manager - Home use^1"
[3] "76B3B165-0BB4-4E3E-B61F-0C0292342CE2^Account Admin^Account Admin^1"    
[4] "B3C0CE51-00EE-4A0A-B208-98653E21AE11^Z:WB:1BENTLEY_ISA_ADMIN:0000^Co-Administrator^1"  
[5] "CBA225BC-680C-4627-A4F6-BED401682816^ReadOnly^ReadOnly^1"
[6] "D80CF5CF-CB6E-4424-9D8F-E29F96EBD4C9^Z:WB:MY_SELECT_CD:0000^Product Delivery - DVD^1"
[7] "E0275936-FBBB-4775-97D3-9A7D19D3E1B4^Z:WB:LICENSE_MANAGER:0000^License Manager^1"

所有元素都包含克拉(^)。所以用^符号进一步分割每个元素将返回四个元素。

但我想加入所有第一个元素,然后加入所有第二个元素,然后加入第三个,依此类推,得到如下结果 -

[0]: 09A880C2-8732-408C-BA09-4AD6F0A65CE9, 24B11B23-1669-403F-A24D-74CE72DFD42A, 6A4A6543-DB9F-46F2-B3C9-62D69D28A0B6, 76B3B165-0BB4-4E3E-B61F-0C0292342CE2, B3C0CE51-00EE-4A0A-B208-98653E21AE11, CBA225BC-680C-4627-A4F6-BED401682816, D80CF5CF-CB6E-4424-9D8F-E29F96EBD4C9, E0275936-FBBB-4775-97D3-9A7D19D3E1B4

[1]: Z:WB:SELECT_DOWNLOAD:0000,Z:WB:TRAINING_SUBSCRIBER:0000, Z:WB:LIC_MGR_HOME_REDL:0000,Account Admin, Z:WB:1BENTLEY_ISA_ADMIN:0000, ReadOnly, Z:WB:MY_SELECT_CD:0000, Z:WB:LICENSE_MANAGER

[2]: Product Delivery - Download, Training Subscriber, License Manager - Home use, Account Admin, Co-Administrator, ReadOnly, Product Delivery - DVD, License Manager
[3]: 1,1,1,1,1,1,1,1

实现这一目标的最快捷,最简单的方法是什么?

修改

这是我到目前为止所尝试的 -

var rolearray = roleDetails.Split(',').Select(s => s.Split('^')).Select(a => new { RoleId = a[0], RoleNme = a[1], FriendlyName = a[2], IsUserInRole = a[3] });

但是这并没有以我需要的方式回归。但是我想加入所有[0],然后加入所有[1]等等

解: 在比较解决方案并在循环中运行10次以查看性能后,我发现Jamiec建议的解决方案花费的时间更少。所以选择这个解决方案。

10 个答案:

答案 0 :(得分:16)

Pure LINQ解决方案:

roleDetails.Split(',')
    .SelectMany(x => x.Split('^').Select((str, idx) => new {str, idx}))
    .GroupBy(x => x.idx)
    .Select(grp => string.Join(", ", grp.Select(x => x.str)))

答案 1 :(得分:10)

最简单的方法就是:

var split = roleDetails.Split(',')
                .Select(x => x.Split('^').ToArray())
                .ToArray();

然后,您将访问像多维锯齿状数组

这样的元素
Console.WriteLine(split[0][0]);
// result: 09A880C2-8732-408C-BA09-4AD6F0A65CE9

实例:http://rextester.com/NEUVOR15080

如果你想要所有元素分组

Console.WriteLine(String.Join(",",split.Select(x => x[0])));
Console.WriteLine(String.Join(",",split.Select(x => x[1])));
Console.WriteLine(String.Join(",",split.Select(x => x[2])));
Console.WriteLine(String.Join(",",split.Select(x => x[3])));

实例:http://rextester.com/BZXLG67151

答案 2 :(得分:5)

您可以在此处使用Linq的聚合和Zip扩展方法。

聚合:对结果中的每个元素执行指定的操作,同时向前传递结果。

Zip: Zip扩展方法对两个集合起作用。它将两个系列中的每个元素一起处理。

var roleDetails = "09A880C2-8732-408C-BA09-4AD6F0A65CE9^Z:WB:SELECT_DOWNLOAD:0000^Product Delivery - Download^1,24B11B23-1669-403F-A24D-74CE72DFD42A^Z:WB:TRAINING_SUBSCRIBER:0000^Training Subscriber^1,6A4A6543-DB9F-46F2-B3C9-62D69D28A0B6^Z:WB:LIC_MGR_HOME_REDL:0000^License Manager - Home use^1,76B3B165-0BB4-4E3E-B61F-0C0292342CE2^Account Admin^Account Admin^1,B3C0CE51-00EE-4A0A-B208-98653E21AE11^Z:WB:1BENTLEY_ISA_ADMIN:0000^Co-Administrator^1,CBA225BC-680C-4627-A4F6-BED401682816^ReadOnly^ReadOnly^1,D80CF5CF-CB6E-4424-9D8F-E29F96EBD4C9^Z:WB:MY_SELECT_CD:0000^Product Delivery - DVD^1,E0275936-FBBB-4775-97D3-9A7D19D3E1B4^Z:WB:LICENSE_MANAGER:0000^License Manager^1";
var rolearray = roleDetails.Split(',')
            .Select(s => s.Split('^'))
            .Aggregate((s1Array, s2Array) => s1Array.Zip(s2Array, (s1, s2) => s1 + "," + s2).ToArray());

答案 3 :(得分:1)

string roleDetails = "09A880C2-8732-408C-BA09-4AD6F0A65CE9^Z:WB:SELECT_DOWNLOAD:0000^Product Delivery - Download^1,24B11B23-1669-403F-A24D-74CE72DFD42A^Z:WB:TRAINING_SUBSCRIBER:0000^Training Subscriber^1,6A4A6543-DB9F-46F2-B3C9-62D69D28A0B6^Z:WB:LIC_MGR_HOME_REDL:0000^License Manager - Home use^1,76B3B165-0BB4-4E3E-B61F-0C0292342CE2^Account Admin^Account Admin^1,B3C0CE51-00EE-4A0A-B208-98653E21AE11^Z:WB:1BENTLEY_ISA_ADMIN:0000^Co-Administrator^1,CBA225BC-680C-4627-A4F6-BED401682816^ReadOnly^ReadOnly^1,D80CF5CF-CB6E-4424-9D8F-E29F96EBD4C9^Z:WB:MY_SELECT_CD:0000^Product Delivery - DVD^1,E0275936-FBBB-4775-97D3-9A7D19D3E1B4^Z:WB:LICENSE_MANAGER:0000^License Manager^1";
    var RawItems = roleDetails.Split(',').Select(x=> x.Split('^'));

    var Items1 = RawItems.Select(x=> x.ElementAt(0));       
    var Items2 = RawItems.Select(x=> x.ElementAt(1));
    var Items3 = RawItems.Select(x=> x.ElementAt(2));
    var Items4 = RawItems.Select(x=> x.ElementAt(3));

答案 4 :(得分:1)

如果你不喜欢LINQ解决方案,这里有一个没有的解决方案:

var result = new string[4];
var i = 0;
foreach(var line in roleDetails.Split(','))
    foreach(var piece in line.Split('^'))
        result[i++ % 4] += (i <= 4 ? "" : ",") + piece;

基本上,你使用一个计数器来分割逗号和插入符号,并使用一个计数器告诉我们要连接哪个数组元素,以及是否使用逗号分隔符。

如果您的初始字符串比此示例中的字符串大得多,请考虑首先创建一个StringBuilders数组,因为这些字符串在连接时效果更好:

var stringBuilders = new StringBuilder[4];
var result = new string[4];
var i = 0;
for (var i = 0; i < 4; i++)
    stringBuilders[i] = new StringBuilder();
foreach(var line in roleDetails.Split(','))
    foreach(var piece in line.Split('^'))
        stringBuilders[i++ % 4].Append((i <= 4 ? "" : ",") + piece);
foreach (var stringBuilder in stringBuilders)
    result[i++ % 4] = stringBuilder.ToString();

答案 5 :(得分:0)

另一个LINQ解决方案。但不像@ Pavel那样干净:

string a = "", b = "", c = "", d = "";
roleDetails.Split(',').ToList().ForEach(x =>
        {
            a += x.Split('^')[0] + ',';
            b += x.Split('^')[1] + ',';
            c += x.Split('^')[2] + ',';
            d += x.Split('^')[3] + ',';
        });
MessageBox.Show(a.Trim(','));
MessageBox.Show(b.Trim(','));
MessageBox.Show(c.Trim(','));
MessageBox.Show(d.Trim(','));

输出:

a = 09A880C2-8732-408C-BA09-4AD6F0A65CE9,24B11B23-1669-403F-A24D-74CE72DFD42A,6A4A6543-DB9F-46F2-B3C9-62D69D28A0B6,76B3B165-0BB4-4E3E-B61F-0C0292342CE2,B3C0CE51-00EE-4A0A-B208-98653E21AE11,CBA225BC-680C-4627-A4F6-BED401682816,D80CF5CF-CB6E-4424-9D8F-E29F96EBD4C9,E0275936-FBBB-4775-97D3-9A7D19D3E1B4
b = Z:WB:SELECT_DOWNLOAD:0000,Z:WB:TRAINING_SUBSCRIBER:0000,Z:WB:LIC_MGR_HOME_REDL:0000,Account Admin,Z:WB:1BENTLEY_ISA_ADMIN:0000,ReadOnly,Z:WB:MY_SELECT_CD:0000,Z:WB:LICENSE_MANAGER:0000
c = Product Delivery - Download,Training Subscriber,License Manager - Home use,Account Admin,Co-Administrator,ReadOnly,Product Delivery - DVD,License Manager
d = 1,1,1,1,1,1,1,1

答案 6 :(得分:0)

相当干净,快速......

var sets = new[]
{
    new List<string>(),
    new List<string>(),
    new List<string>(),
    new List<string>(),
};

foreach (var role in roleDetails.Split(','))
{
    var details = role.Split('^');
    sets[0].Add(details[0]);
    sets[1].Add(details[1]);
    sets[2].Add(details[2]);
    sets[3].Add(details[3]);
}

var lines = sets.Select(set => string.Join(",", set)).ToArray();

...要理解的小坚果,并没有真正保存任何性能......

var ret = roleDetails.Split(',')
        .Aggregate(seed: new { SBS = new[] { new StringBuilder(), new StringBuilder(),
                                             new StringBuilder(), new StringBuilder(), },
                               Start = true },

        func: (seed, role) =>
        {
            var details = role.Split('^');

            if (seed.Start)
            {
                seed.SBS[0].Append(details[0]);
                seed.SBS[1].Append(details[1]);
                seed.SBS[2].Append(details[2]);
                seed.SBS[3].Append(details[3]);

                return new
                {
                    seed.SBS,
                    Start = false,
                };
            }
            else
            {
                seed.SBS[0].Append(',').Append(details[0]);
                seed.SBS[1].Append(',').Append(details[1]);
                seed.SBS[2].Append(',').Append(details[2]);
                seed.SBS[3].Append(',').Append(details[3]);

                return seed;
            }
        },
        resultSelector: result => result.SBS.Select(sb => sb.ToString()).ToArray()
        );

答案 7 :(得分:-2)

这样的事情应该有效。

var roleDetails = "09A880C2-8732-408C-BA09-4AD6F0A65CE9^Z:WB:SELECT_DOWNLOAD:0000^Product Delivery - Download^1,24B11B23-1669-403F-A24D-74CE72DFD42A^Z:WB:TRAINING_SUBSCRIBER:0000^Training Subscriber^1,6A4A6543-DB9F-46F2-B3C9-62D69D28A0B6^Z:WB:LIC_MGR_HOME_REDL:0000^License Manager - Home use^1,76B3B165-0BB4-4E3E-B61F-0C0292342CE2^Account Admin^Account Admin^1,B3C0CE51-00EE-4A0A-B208-98653E21AE11^Z:WB:1BENTLEY_ISA_ADMIN:0000^Co-Administrator^1,CBA225BC-680C-4627-A4F6-BED401682816^ReadOnly^ReadOnly^1,D80CF5CF-CB6E-4424-9D8F-E29F96EBD4C9^Z:WB:MY_SELECT_CD:0000^Product Delivery - DVD^1,E0275936-FBBB-4775-97D3-9A7D19D3E1B4^Z:WB:LICENSE_MANAGER:0000^License Manager^1";
        var firstSplit=roleDetails.Split(',');
        var final = new string[4];
        foreach(string Str in firstSplit)
        {
            var secondSplit=Str.Split('^');
            for (int i = 0; i < 4; i++)
            {
                final[i] += secondSplit[i] + ", ";
            }
        }

我会留给你删除最后一个逗号。

答案 8 :(得分:-2)

您可以在此使用Tuple

var roles = roleDetails.Split(',')
            .Select(x => x.Split('^'))
            .Where(x=>x.Length==4)
            .Select(x=> 
             new Tuple<string, string, string, string>(x[0], x[1], x[2], x[3]))
            .ToList();

            var item1 = string.Join(",", roles.Select(x=>x.Item1).ToArray());     
            var item2 = string.Join(",", roles.Select(x => x.Item2).ToArray());
            var item3 = string.Join(",", roles.Select(x => x.Item3).ToArray());
            var item4 = string.Join(",", roles.Select(x => x.Item4).ToArray());

答案 9 :(得分:-3)

你的尝试试图在一行中做所有事情,这使你更难理解发生了什么。

您已经使用了所需的所有工具(Select()Split())。如果通过将所有代码分隔成单独的代码行来使代码更具可读性,那么找到自己的方式会更容易:

//Your data string
string myDataString = "..."; 

//Your data string, separated into a list of rows (each row is a string)
var myDataRows = myDataString.Split(',');

//Your data string, separated into a list of rows (each row is a STRING ARRAY)
var myDataRowsAsStringArrays = myDataRows.Select(row => row.Split('^'))

现在,您需要做的就是检索正确的数据。

var firstColumnValues  = myDataRowsAsStringArrays.Select(row => row[0]);
var secondColumnValues = myDataRowsAsStringArrays.Select(row => row[1]);
var thirdColumnValues  = myDataRowsAsStringArrays.Select(row => row[2]);
var fourthColumnValues = myDataRowsAsStringArrays.Select(row => row[3]);

如果你这样选择,你可以将这些值加入一个逗号分隔的字符串中:

var firstColumnString  =  String.Join(", ", firstColumnValues);
var secondColumnString =  String.Join(", ", secondColumnValues);
var thirdColumnString  =  String.Join(", ", thirdColumnValues);
var fourthColumnString =  String.Join(", ", fourthColumnValues);