如何比较多维字符串数组?

时间:2014-01-02 17:15:10

标签: c# arrays string multidimensional-array

我想比较2个字段。即机器和通行证。

我想连接'Color'取决于Machine的值并传递。

--------------|------------------|------------
 Color1       | Machine 1        | Pass 1 
--------------|------------------|------------
 Color2       | Machine 2        | Pass 1 
--------------|------------------|------------
 Color3       | Machine 1        | Pass 1 
--------------|------------------|------------
 Color4       | Machine 1        | Pass 2 
--------------|------------------|------------
 Color5       | Machine 2        | Pass 1 
--------------|------------------|------------
 Color6       | Machine 2        | Pass 2 
--------------|------------------|------------

我想要的结果如下。

  1. Machine1& Color1 / Color3 PASS1
  2. Color2 / Color5 for Machine2& PASS2
  3. Color4 for Machine1& PASS2
  4. Color6 for Machine2& PASS2
  5. 我不知道如何得到这个结果。尝试了很多方法,但没有按照我想要的方式得到它

4 个答案:

答案 0 :(得分:6)

首先,从概念上讲,你真正拥有的是具有颜色,机器和传递值的复杂对象的单个维度。将其存储在二维数组中并不是一个好主意。更好的表示是某种自定义类型的List,所以我们先进行转换。

首先,我们将定义一个自定义类型来表示输入数据:

public class MachinePass//TODO consider renaming
{
    public string Color { get; set; }
    public string Machine { get; set; }
    public string Pass { get; set; }
}

然后我们将解析我们的输入并将其放入适当的结构中:

var list = new List<MachinePass>();
for (int i = 0; i < data.GetLength(0); i++)
{
    var next = new MachinePass();
    next.Color = data[i, 0];
    next.Machine = data[i, 1];
    next.Pass = data[i, 2];
    list.Add(next);
}

现在我们有了这个,我们可以应用我们的业务逻辑。在这种情况下,您要做的是通过机器和传递对这些行进行分组,然后获取这些组的颜色。 GroupBy LINQ运算符使这非常简单:

var query = list.GroupBy(row => new { row.Machine, row.Pass }
    , row => row.Color);

然后我们可以用定义的格式打印出这个查询的结果:

foreach(var group in query)
    Console.WriteLine("{0} for {1} & {2}",
        string.Join("/", group),
        group.Key.Machine,
        group.Key.Pass);

答案 1 :(得分:1)

这是你的答案,

private void button1_Click(object sender, EventArgs e)
{
    var ary = new[]
    {
        "Color1       | Machine 1     | Pass 1 ",
        "Color2       | Machine 2     | Pass 1 ",
        "Color3       | Machine 1     | Pass 1 ",
        "Color4       | Machine 1     | Pass 2 ",
        "Color5       | Machine 2     | Pass 1 ",
        "Color6       | Machine 2     | Pass 2 "
    };

    var seprated = from x in ary.Select(x => x.Split('|'))
                    select new
                    {
                        key = x[1].Trim() + "&" + x[2].Trim(),
                        value = x[0]
                    };

    var sb = new StringBuilder();
    foreach (var key in seprated.Select(x => x.key).Distinct())
    {
        var colors = seprated.Where(x => x.key == key).Select(x => x.value.Trim()).ToArray();
        sb.AppendLine(string.Format("{0} for {1}", string.Join("/", colors), key));
    }

    textBox1.Text = sb.ToString();
}

sb.toString()有结果:

机器1的Color1 / Color3&amp; Pass 1

Color 2 / Color5 for Machine 2&amp; Pass 1

Machine 1 for Machine 1&amp; Pass 2

机器2和通行证2的Color6

答案 2 :(得分:1)

        var multidimensionalArray = new[,]
            {
                {"Color1", "Machine 1", "Pass 1"},
                {"Color2", "Machine 2", "Pass 1"},
                {"Color3", "Machine 1", "Pass 1"},
                {"Color4", "Machine 1", "Pass 2"},
                {"Color5", "Machine 2", "Pass 1"},
                {"Color6", "Machine 2", "Pass 2"}
            };

        var tuple = new List<Tuple<string, string, string>>();
        for (var i = 0; i < multidimensionalArray.Length/3-1; i++)
        {
            tuple.Add(new Tuple<string, string, string>(multidimensionalArray[i, 0], multidimensionalArray[i, 1], multidimensionalArray[i, 2]));
        }

        foreach (var el in tuple.GroupBy(x => String.Format("{0} & {1}", x.Item2, x.Item3), y => y.Item1))
        {
            Console.WriteLine(String.Join("/", el) + " for " + el.Key);
        }

答案 3 :(得分:1)

您没有提供类定义,所以我假设它是以下

class PaintMachineInfo
{
    public string ColorName {get; set;}
    public string MachineName {get; set;}
    public string Pass {get; set;}
}

您可以使用.ToLookup(轻松获得所需的结果,它允许您执行的操作是提供密钥,它将为您提供与该密钥匹配的IEnumerable结果。

我喜欢使用查找键的自定义类而不是Tuple,因为它使你看到的更加明显,创建类的代码也不多。

private static void Main(string[] args)
{
    List<PaintMachineInfo> info = GenerateInfo();

    var filteredResults = info.ToLookup(line => new PaintMachineLookup(line.MachineName, line.Pass), line => line.ColorName);

    //Contains a IEnumerable<string> containing the elements "Color1" and "Color3"
    var result1 = filteredResults[new PaintMachineLookup("Machine 1", "Pass 1")];

}

private static List<PaintMachineInfo> GenerateInfo()
{
    //...
}

class PaintMachineInfo
{
    public string ColorName { get; set; }
    public string MachineName { get; set; }
    public string Pass { get; set; }
}

internal class PaintMachineLookup
{
    public PaintMachineLookup(string machineName, string pass)
    {
        MachineName = machineName;
        Pass = pass;
    }
    public string MachineName { get; private set; }
    public string Pass { get; private set; }

    public override int GetHashCode()
    {
        unchecked
        {
            int x = 27;
            x = x * 11 + MachineName.GetHashCode();
            x = x * 11 + Pass.GetHashCode();
            return x;
        }
    }

    public override bool Equals(object obj)
    {
        var other = obj as PaintMachineLookup;
        if (other == null)
            return false;

        return MachineName.Equals(other.MachineName) && Pass.Equals(other.Pass);
    }
}