为了账号安全,请及时绑定邮箱和手机立即绑定

在 C# 中对二维数组进行分组?

在 C# 中对二维数组进行分组?

C#
ITMISS 2021-08-22 18:03:16
我有一个二维字符串数组:string[,] arr = new string[3,3]{  { "a", "b", "c" },   { "a", "b", "c" },   { "d", "e", "f" }, }我想得到的结果是:a,b,c = 2d,e,f = 1我试过:List<List<string>> lLString = new List<List<string>>();string[,] stringArray2D = new string[3, 3] {    { "a", "b", "c" },     { "a", "b", "c" },     { "d", "e", "f" }, };for (int i = 0; i < stringArray2D.GetLength(0); i++) {    List<string> temp = new List<string>();    for (int j = 0; j < stringArray2D.GetLength(1); j++) {         temp.Add(stringArray2D[i,j]);    }    lLString.Add(temp);}试图通过这样做来解决它:lLString.GroupBy (ls => ls);但似乎不对
查看完整描述

3 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

您可以直接使用锯齿状数组,例如:


string[][] arrayJagged = new[]

{

    new[] { "a", "b", "c" },

    new[] { "a", "b", "c" },

    new[] { "d", "e", "f" },

    new[] { "g", "h", "i" },

};

但是你想在过去的废墟中挖掘并使用多维数组,只是为了让一切变得更加复杂。


string[,] stringArray2D = new string[,] 

{

    { "a", "b", "c" },

    { "a", "b", "c" },

    { "d", "e", "f" },

    { "g", "h", "i" },

};

然后我们必须将多维数组转换为锯齿状数组:


string[][] arrayJagged = new string[stringArray2D.GetLength(0)][];


int length2 = stringArray2D.GetLength(1);


for (int i = 0; i < arrayJagged.Length; i++)

{

    arrayJagged[i] = new string[length2];


    for (int j = 0; j < length2; j++)

    {

        arrayJagged[i][j] = stringArray2D[i, j];

    }

}

请注意,您实际上并不需要 a,List<List<string>>因为最终锯齿状数组的维度是预先确定的。


然后你可以.GroupBy()使用锯齿状数组,并.Count()在每组上做一个:


var grouped = arrayJagged.GroupBy(x => x, ArrayEqualityComparer<string>.Default)

    .Select(x => new

    {

        x.Key,

        Count = x.Count()

    })

    .ToArray();

请注意,.NET 没有用于数组的默认相等比较器,因此您需要定义一个,以显示.GroupBy()如何检查元素的相等性:


// Simple T[] IEqualityComparer<>

public sealed class ArrayEqualityComparer<T> : IEqualityComparer<T[]>, IEqualityComparer

{

    // One instance is more than enough

    public static readonly ArrayEqualityComparer<T> Default = new ArrayEqualityComparer<T>();


    // We lazily define it if necessary

    private readonly IEqualityComparer<T> equalityComparer;


    public ArrayEqualityComparer()

    {

        equalityComparer = EqualityComparer<T>.Default;

    }


    public ArrayEqualityComparer(IEqualityComparer<T> equalityComparer)

    {

        this.equalityComparer = equalityComparer;

    }


    /* IEqualityComparer<T[]> */


    public bool Equals(T[] x, T[] y)

    {

        if (x == null)

        {

            if (y == null)

            {

                return true;

            }


            return false;

        }


        if (y == null)

        {

            return false;

        }


        return EqualsNotNull(x, y);

    }


    public int GetHashCode(T[] obj)

    {

        unchecked

        {

            int hash = 17;


            if (obj != null)

            {

                // This one will help distinguish between null and empty:

                // hash(null) == 17, hash(empty) == 17 * 23

                hash = (hash * 23) + obj.Length;


                for (int i = 0; i < obj.Length; i++)

                {

                    hash = (hash * 23) + obj[i].GetHashCode();

                }

            }


            return hash;

        }

    }


    /* IEqualityComparer */


    bool IEqualityComparer.Equals(object x, object y)

    {

        if (x == y)

        {

            return true;

        }


        if (x == null || y == null)

        {

            return false;

        }


        var x2 = x as T[];


        if (x2 == null)

        {

            throw new ArgumentException("x");

        }


        var y2 = y as T[];


        if (y2 == null)

        {

            throw new ArgumentException("y");

        }


        return EqualsNotNull(x2, y2);

    }


    int IEqualityComparer.GetHashCode(object obj)

    {

        T[] obj2;


        if (obj != null)

        {

            obj2 = obj as T[];


            if (obj2 == null)

            {

                throw new ArgumentException("obj");

            }

        }

        else

        {

            obj2 = null;

        }


        return GetHashCode(obj2);

    }


    /* Implementation */


    private bool EqualsNotNull(T[] x, T[] y)

    {

        if (x.Length != y.Length)

        {

            return false;

        }


        if (x.Length != 0)

        {

            for (int i = 0; i < x.Length; i++)

            {

                if (!equalityComparer.Equals(x[i], y[i]))

                {

                    return false;

                }

            }

        }


        return true;

    }

}


查看完整回答
反对 回复 2021-08-22
?
千巷猫影

TA贡献1829条经验 获得超7个赞

创建一个覆盖等于的类


public static void GroupList()

{

    List<ListComp> lLString = new List<ListComp>();

    string[,] stringArray2D = new string[3, 3] { { "a", "b", "c" },

                                                 { "a", "b", "c" },

                                                 { "d", "e", "f" },

                                                };

    for (int i = 0; i<stringArray2D.GetLength(0); i++) {

        ListComp temp = new ListComp();

        for (int j = 0; j<stringArray2D.GetLength(1); j++) { 

            temp.Add(stringArray2D[i, j]);

        }

        lLString.Add(temp);

    }

    var gr = lLString.GroupBy(i => i);


    foreach (var g in gr)

    {

        Debug.WriteLine($"{g.Key} = {g.Count()}");

    }

    Debug.WriteLine("");

}

public class ListComp : List<string>

{

    public override string ToString()

    {

        return string.Join(",", this);

    }

    public override bool Equals(object obj)

    {

        ListComp listComp = obj as ListComp;

        if (listComp == null)

            return false;

        else

            return Equals(listComp);

    }

    public bool Equals(ListComp listComp)

    {

        if (listComp == null)

            return false;


        return this.SequenceEqual(listComp);

    }

    public override int GetHashCode()

    {

        int hash = 1;

        foreach(string s in this)

        {

            hash *= s.GetHashCode();

        }

        return hash;

    }

    public ListComp (List<string> listComp)

    {

        this.AddRange(listComp);

    }

    public ListComp()

    {

    }

}


查看完整回答
反对 回复 2021-08-22
?
婷婷同学_

TA贡献1844条经验 获得超8个赞

使用类似于您使用的循环的基本 for 循环创建字符串列表。然后使用GroupBy.


string[,] arr = new string[3, 3]

{

        { "a", "b", "c" },

        { "a", "b", "c" },

        { "d", "e", "f" },

};


int dim1 = arr.GetLength(0);

int dim2 = arr.GetLength(1);


List<string> temp = new List<string>();

string st;

for (int i = 0; i < dim1; i++)

{

    st = "";

    for (int j = 0; j < dim2; j++)

        st += arr[i, j] + ",";

    temp.Add(st);

}


var gr = temp.GroupBy(i => i);


foreach (var g in gr)

    Console.WriteLine($"{g.Key} = {g.Count()}");

输出: 

a,b,c, = 2

d,e,f, = 1


查看完整回答
反对 回复 2021-08-22
  • 3 回答
  • 0 关注
  • 331 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信