C#在匹配时连接字符串的记录

本文关键字:字符串 记录 连接 | 更新日期: 2023-09-27 17:59:14

我正在生成一组记录,其中每条记录由三个字符串组成。生成的记录数量是动态的,因为用户可以添加任意数量的记录。

我需要浏览这组记录,并根据三个字符串中的两个生成/组合记录,第三个字符串连接在一起。我知道这可能不清楚,但我提供了一些用户记录集的样本日期,以及我需要的结果。

用户生成的记录:

记录1:"AAA"、"BBB"、"DEF"

记录2:"AAA"、"BBB"、"QEW"

记录3:"RRR","WWW","123"

记录4:"RRR","WWW","321"

记录5:"XXX"、"WWW"、"421"

我需要的结果:

记录1:"AAA"、"BBB"、"DEFQEW"

记录2:"RRR"、"WWW"、"123321"

记录3:"XXX,"WWW","421"

此外,我应该将记录存储在什么位置,以便根据需要操作日期?

我不熟悉LINQ,所以如果你建议我举几个例子,我会很感激的。非常感谢。

编辑

我在数据行中循环生成字符串。我可以将它们像列表(字符串)或您建议的任何东西一样存储。

C#在匹配时连接字符串的记录

如果没有更多的上下文,很难提出最佳解决方案。一个简单的Linq GroupBy就可以做到这一点:

// Assuming that each array has exactly 3 elements
IEnumerable<string[]> records; // Initialize this
var groupedRecords = records
    .GroupBy(
        // Group the records by the two first values
        r => new { a = r[0], b = r[1] },
        // Concatenate the matching records
        (k, g) => new { k.a, k.b, string.Join("", g.Select(r => r[2]) }
    );

在这个例子中,我假设每个记录只是一个由3个元素组成的数组。您可能希望创建一个能够正确表示记录的类型,但代码应该很难适应。

如果是IEnumerable<CustomType>,其中CustomType是具有三个属性的类:

var result = records
    .GroupBy(x => new { x.Prop1, x.Prop2 })
    .Select(g => new CustomType 
    {
        Prop1 = g.Key.Prop1,
        Prop2 = g.Key.Prop2,
        Prop3 = String.Join(", ", g.Select(x => x.Prop3))
    });

如果是DataTable,如您的问题中所述:

var result = table.AsEnumerable()
    .GroupBy(row => new { Col1 = row.Field<string>(0), Col2 = row.Field<string>(1) })
    .Select(g => new
    {
        Col1 = g.Key.Col1,
        Col2 = g.Key.Col2,
        Col3 = String.Join(", ", g.Select(row => row.Field<string>(2)))
    });

试试这个

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Col1", typeof(string));
            dt.Columns.Add("Col2", typeof(string));
            dt.Columns.Add("Col3", typeof(string));
            dt.Rows.Add(new object[] {"AAA","BBB","DEF"});
            dt.Rows.Add(new object[] {"AAA","BBB","QEW"});
            dt.Rows.Add(new object[] {"RRR","WWW","123"});
            dt.Rows.Add(new object[] {"RRR","WWW","321"});
            dt.Rows.Add(new object[] {"XXX","WWW","421"});
            var results = dt.AsEnumerable()
                .GroupBy(x => new  {col1 =  x.Field<string>("Col1"), col2 = x.Field<string>("Col2") })
                .Select(x => new { 
                    col1 = x.FirstOrDefault().Field<string>("Col1"),
                    col2 = x.FirstOrDefault().Field<string>("Col2"),
                    col3 = string.Join("",x.Select(y => y.Field<string>("Col3")).ToArray())
                })
                .ToList();
        }
    }
}
​
// here's the solution thanks to jdweng and Tim - I adjusted it to work with 5 columns based on 3 columns.
var result = toDisplay.AsEnumerable()
             .GroupBy(x => new { Col1 = x.Field<string>("rItem"),
                                 Col2 = x.Field<string>("rMaterial"),
                                 Col3 = x.Field<string>("rSpecs")})
            .Select(g => new
            {
                Col1 = g.Key.Col1,
                Col2 = g.Key.Col2,
                Col3 = g.Key.Col3,
                Col4 = String.Join(", ", g.Select(row => row.Field<string>("rQuantity"))),
                Col5 = String.Join(", ", g.Select(row => row.Field<string>("rOptional"))),
            });