Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 识别和分组字符串集合中的类似项_C#_.net_Linq - Fatal编程技术网

C# 识别和分组字符串集合中的类似项

C# 识别和分组字符串集合中的类似项,c#,.net,linq,C#,.net,Linq,我有一组字符串,如下所示: List<string> codes = new List<string> { "44.01", "44.02", "44.03", "44.04", "44.05", "44.06", "44.07", "44.08", "46", "47.10" }; 列表代码=新列表 { "44.01", "44.02", "44.03", "44.04", "44.05", "44.06", "44.07", "44.08", "46", "

我有一组字符串,如下所示:

List<string> codes = new List<string>
{
    "44.01", "44.02", "44.03", "44.04", "44.05", "44.06", "44.07", "44.08", "46", "47.10"
};
列表代码=新列表
{
"44.01", "44.02", "44.03", "44.04", "44.05", "44.06", "44.07", "44.08", "46", "47.10"
};
每个字符串由两个组件组成,两个组件之间用一个句号分隔——前缀代码和子代码。有些字符串没有子代码

我希望能够组合前缀相同的字符串,并将其与其他代码一起输出,如下所示:

44(01,02,03,04,05,06,07,08),46,47.10

我被困在第一个障碍上,那就是如何识别前缀值相同的代码并将其分组,这样我就可以将它们组合成一个字符串,正如上面所示

概述想法:

  • 使用
    字典
    收集结果

  • 在列表上的循环中,使用
    string.split()
    。。第一个元素将是您的字典键。。。如果密钥还不存在,则在那里创建一个新的
    列表

  • 如果拆分的结果有第二个元素,请将其附加到列表中

  • 使用第二个循环将该字典格式化为输出字符串

当然,linq也是可能的,例如

List<string> codes = new List<string>() {
    "44.01", "44.05", "47", "42.02", "44.03" };

var result = string.Join(",",
    codes.OrderBy(x => x)
    .Select(x => x.Split('.'))
    .GroupBy(x => x[0])
    .Select((x) =>
    {
        if (x.Count() == 0) return x.Key;
        else if (x.Count() == 1) return string.Join(".", x.First());
        else return x.Key + "(" + string.Join(",", x.Select(e => e[1]).ToArray()) + ")";
    }).ToArray());
列表代码=新列表(){
"44.01", "44.05", "47", "42.02", "44.03" };
var result=string.Join(“,”,
codes.OrderBy(x=>x)
.选择(x=>x.Split('.'))
.GroupBy(x=>x[0])
.选择((x)=>
{
如果(x.Count()==0)返回x.Key;
如果(x.Count()==1)返回string.Join(“.”,x.First());
否则返回x.Key+”(“+string.Join(“,”,x.Select(e=>e[1]).ToArray())+”);
}).ToArray());
一定要爱林克。。。哈哈。。。我认为这是一个怪物。

概述了这个想法:

  • 使用
    字典
    收集结果

  • 在列表上的循环中,使用
    string.split()
    。。第一个元素将是您的字典键。。。如果密钥还不存在,则在那里创建一个新的
    列表

  • 如果拆分的结果有第二个元素,请将其附加到列表中

  • 使用第二个循环将该字典格式化为输出字符串

当然,linq也是可能的,例如

List<string> codes = new List<string>() {
    "44.01", "44.05", "47", "42.02", "44.03" };

var result = string.Join(",",
    codes.OrderBy(x => x)
    .Select(x => x.Split('.'))
    .GroupBy(x => x[0])
    .Select((x) =>
    {
        if (x.Count() == 0) return x.Key;
        else if (x.Count() == 1) return string.Join(".", x.First());
        else return x.Key + "(" + string.Join(",", x.Select(e => e[1]).ToArray()) + ")";
    }).ToArray());
列表代码=新列表(){
"44.01", "44.05", "47", "42.02", "44.03" };
var result=string.Join(“,”,
codes.OrderBy(x=>x)
.选择(x=>x.Split('.'))
.GroupBy(x=>x[0])
.选择((x)=>
{
如果(x.Count()==0)返回x.Key;
如果(x.Count()==1)返回string.Join(“.”,x.First());
否则返回x.Key+”(“+string.Join(“,”,x.Select(e=>e[1]).ToArray())+”);
}).ToArray());

一定要爱林克。。。哈哈。。。我认为这是一个怪兽。

总体思路,但我确信用
Regex
替换
子字符串
调用也会更好

List<string> newCodes = new List<string>()
foreach (string sub1 in codes.Select(item => item.Substring(0,2)).Distinct)
{
    StringBuilder code = new StringBuilder();
    code.Append("sub1(");
    foreach (string sub2 in codes.Where(item => item.Substring(0,2) == sub1).Select(item => item.Substring(2))
        code.Append(sub2 + ",");
    code.Append(")");
    newCodes.Add(code.ToString());
}
List newcode=newlist()
foreach(代码中的字符串sub1.Select(item=>item.Substring(0,2)).Distinct)
{
StringBuilder代码=新的StringBuilder();
代码。追加(“sub1(”);
foreach(代码中的字符串sub2.Where(item=>item.Substring(0,2)==sub1)。选择(item=>item.Substring(2))
代码.追加(sub2+“,”);
代码。追加(“)”;
newCodes.Add(code.ToString());
}

总体思路,但我确信用
Regex
替换
子字符串
调用也会更好

List<string> newCodes = new List<string>()
foreach (string sub1 in codes.Select(item => item.Substring(0,2)).Distinct)
{
    StringBuilder code = new StringBuilder();
    code.Append("sub1(");
    foreach (string sub2 in codes.Where(item => item.Substring(0,2) == sub1).Select(item => item.Substring(2))
        code.Append(sub2 + ",");
    code.Append(")");
    newCodes.Add(code.ToString());
}
List newcode=newlist()
foreach(代码中的字符串sub1.Select(item=>item.Substring(0,2)).Distinct)
{
StringBuilder代码=新的StringBuilder();
代码。追加(“sub1(”);
foreach(代码中的字符串sub2.Where(item=>item.Substring(0,2)==sub1)。选择(item=>item.Substring(2))
代码.追加(sub2+“,”);
代码。追加(“)”;
newCodes.Add(code.ToString());
}
您可以执行以下操作:

var query = codes.Select(c => 
    new
    {
        SplitArray = c.Split('.'),  //to avoid multiple split
        Value = c
    })
    .Select(c => new
    {
        Prefix = c.SplitArray.First(), //you can avoid multiple split if you split first and use it later
        PostFix = c.SplitArray.Last(),
        Value = c.Value,
    })
    .GroupBy(r => r.Prefix)
    .Select(grp => new
    {
        Key = grp.Key,
        Items = grp.Count() > 1 ? String.Join(",", grp.Select(t => t.PostFix)) : "",
        Value = grp.First().Value,
    });
这就是它的工作原理:

  • 在分隔符上拆分列表中的每个项目,并使用
    前缀
    后缀
    和原始
  • 后一组在
    前缀上
  • 之后,使用
    string.Join
对于输出:

foreach (var item in query)
{
    if(String.IsNullOrWhiteSpace(item.Items))
        Console.WriteLine(item.Value);
    else
        Console.WriteLine("{0}({1})", item.Key, item.Items);
}
产出将是:

44(01,02,03,04,05,06,07,08)
46
47.10
你可以做:

var query = codes.Select(c => 
    new
    {
        SplitArray = c.Split('.'),  //to avoid multiple split
        Value = c
    })
    .Select(c => new
    {
        Prefix = c.SplitArray.First(), //you can avoid multiple split if you split first and use it later
        PostFix = c.SplitArray.Last(),
        Value = c.Value,
    })
    .GroupBy(r => r.Prefix)
    .Select(grp => new
    {
        Key = grp.Key,
        Items = grp.Count() > 1 ? String.Join(",", grp.Select(t => t.PostFix)) : "",
        Value = grp.First().Value,
    });
这就是它的工作原理:

  • 在分隔符上拆分列表中的每个项目,并使用
    前缀
    后缀
    和原始
  • 后一组在
    前缀上
  • 之后,使用
    string.Join
对于输出:

foreach (var item in query)
{
    if(String.IsNullOrWhiteSpace(item.Items))
        Console.WriteLine(item.Value);
    else
        Console.WriteLine("{0}({1})", item.Key, item.Items);
}
产出将是:

44(01,02,03,04,05,06,07,08)
46
47.10

你可以走两条路…我可以看到你制作一个
字典
,这样你就可以把“44”映射到一个{.01“,.02“,.03”等的列表中。这需要你在将代码添加到这个列表之前先处理代码(即,将代码的两部分分开,并处理只有一部分的情况)

或者你可以将它们放入一个分类数据集中,并提供你自己的比较器,它知道这些是代码以及如何对它们进行排序(至少这比按字母顺序分组更可靠)。不过,在这个分类数据集中进行迭代仍然需要特殊的逻辑,因此上面的Dictionary to List选项可能仍然更可取


在这两种情况下,您仍然需要处理代码中没有第二个元素的特殊情况“46”。在字典示例中,您会在列表中插入一个字符串.Empty吗?不确定如果您得到一个列表{“46”,“46.1”},您会输出什么--您会显示为“46(null,1)”还是…“46(0,1)”…或“46(,1)”或“46(1)”还是“46(1)”?

你可以有两种方法…我可以看到你制作一个
字典
,这样你就可以将“44”映射到一个{.01“,.02“,.03”等的列表中。这需要你在将代码添加到这个列表之前处理代码(即,分离代码的两个部分,并处理只有一个部分的情况)