Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.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# 用于索引到IEnumerableObjects的动态LINQ查询字符串,用于高效多维数组排序_C#_Linq_Sorting_Multidimensional Array - Fatal编程技术网

C# 用于索引到IEnumerableObjects的动态LINQ查询字符串,用于高效多维数组排序

C# 用于索引到IEnumerableObjects的动态LINQ查询字符串,用于高效多维数组排序,c#,linq,sorting,multidimensional-array,C#,Linq,Sorting,Multidimensional Array,我一直在尝试找出一种最有效、最灵活的方法,通过多列对多维数组进行排序,排序条件直到运行时才知道 起初,我用三种不同的方法处理了DataTables和排序:DataTable.Select、DataView.Sort和在DataTable上使用LINQ。前两种方法允许您通过构建排序字符串在运行时动态指定排序条件 经过一点研究,我发现了动态LINQ,它允许您通过类似于传递到DataTable.Select或DataView.Sort的字符串来执行OrderBy、ThenBy等操作: 还有关于并行L

我一直在尝试找出一种最有效、最灵活的方法,通过多列对多维数组进行排序,排序条件直到运行时才知道

起初,我用三种不同的方法处理了DataTables和排序:DataTable.Select、DataView.Sort和在DataTable上使用LINQ。前两种方法允许您通过构建排序字符串在运行时动态指定排序条件

经过一点研究,我发现了动态LINQ,它允许您通过类似于传递到DataTable.Select或DataView.Sort的字符串来执行OrderBy、ThenBy等操作:

还有关于并行LINQ,以便您可以在排序中使用多个核心(与数据表不兼容,因为它们不是线程安全的):

因此,我认为我可以基于运行时提供的多个排序条件,以比使用DataTable更有效的方法执行多维数组排序

我想出了下面的代码。但是,如果我将数据包装在自定义对象中,我只能使动态LINQ和并行LINQ工作,因为我不知道如何为列表或交错数组构建动态LINQ查询字符串

有人知道我需要对动态LINQ的查询字符串做什么更改才能使排序工作吗?我试图在下面的代码中更正的字符串是“0 ASC,2 DESC,1 ASC”

请注意,当我将数据包装到一个名为Row的自定义对象中时,我可以很好地构建DLINQ字符串并对其进行正确排序。但是,最好能消除这将产生的额外开销

下面的代码按3列对测试数组进行排序。对于使用LINQ和动态LINQ的各种方法,我混合使用了测试用例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;

namespace MultiDimensionalArraySorting
{
    class Program
    {
    static void Main(string[] args)
    {

        var testArray = new IComparable[,]{
            {1, "a", new DateTime(2000, 1, 1)},
            {2, "a", new DateTime(2000, 1, 2)},
            {1, "c", new DateTime(2000, 1, 1)},
            {5, "a", new DateTime(2000, 1, 1)},
            {2, "a", new DateTime(2000, 1, 1)},
        };
        int numRows = testArray.GetLength(0);
        int numCols = testArray.GetLength(1);

        var listOfRows = TwoDimensionalArrayToListOfRows(testArray);

        var aSortedUsingLinqOnListOfRows = new IComparable[numRows, numCols];
        var sortedByLinqOnListOfRows = listOfRows.AsParallel().OrderBy(r => r.Values[0]).ThenByDescending(r => r.Values[2]).ThenBy(r => r.Values[1]);
        ListOfRowsToTwoDimensionalArray(sortedByLinqOnListOfRows, ref aSortedUsingLinqOnListOfRows);
        Console.WriteLine("\nLinq on list of custom type:");
        PrintMultiDimensionalArray(aSortedUsingLinqOnListOfRows);

        var aSortedUsingDLinqOnListOfRows = new IComparable[numRows, numCols];
        var sortedByDLinqOnListOfRows = listOfRows.AsParallel().OrderBy("Values[0] ASC, Values[2] DESC, Values[1] ASC");
        ListOfRowsToTwoDimensionalArray(sortedByDLinqOnListOfRows, ref aSortedUsingDLinqOnListOfRows);
        Console.WriteLine("\n\nDLinq on list of custom type:");
        PrintMultiDimensionalArray(aSortedUsingDLinqOnListOfRows);

        var listOfList = TwoDimensionalArrayToListOfList(testArray);

        var aSortedUsingLinqOnListOfList = new IComparable[numRows, numCols];
        var sortedByLinqOnListOfList = listOfList.AsParallel().OrderBy(r => r[0]).ThenByDescending(r => r[2]).ThenBy(r => r[1]);
        ListOfListToTwoDimensionalArray(sortedByLinqOnListOfList, ref aSortedUsingLinqOnListOfList);
        Console.WriteLine("\n\nLinq on list of list:");
        PrintMultiDimensionalArray(aSortedUsingLinqOnListOfList);

        var aSortedUsingDLinqOnListOfList = new IComparable[numRows, numCols];
        var sortedByDLinqOnListOfList = listOfList.AsParallel().OrderBy("0 ASC, 2 DESC, 1 ASC"); //The string provided is incorrect here
        ListOfListToTwoDimensionalArray(sortedByDLinqOnListOfList, ref aSortedUsingDLinqOnListOfList);
        Console.WriteLine("\n\nDLinq on list of list (incorrect):");
        PrintMultiDimensionalArray(aSortedUsingDLinqOnListOfList);

        var jaggedArray = TwoDimensionalArrayToJagged(testArray);

        var aSortedUsingLinqOnJagged = new IComparable[numRows, numCols];
        var sortedJaggedLinq = jaggedArray.AsParallel().OrderBy(r => r[0]).ThenByDescending(r => r[2]).ThenBy(r => r[1]);
        JaggedArrayToTwoDimensional(sortedJaggedLinq, ref aSortedUsingLinqOnJagged);
        Console.WriteLine("\n\nLinq on jagged array:");
        PrintMultiDimensionalArray(aSortedUsingLinqOnJagged);

        var aSortedUsingDLinqOnJagged = new IComparable[numRows, numCols];
        var sortedUsingDLinqOnJagged = jaggedArray.AsParallel().OrderBy("0 ASC, 2 DESC, 1 ASC"); //The string provided is incorrect here
        JaggedArrayToTwoDimensional(sortedUsingDLinqOnJagged, ref aSortedUsingDLinqOnJagged);
        Console.WriteLine("\n\nDLinq on jagged array(incorrect):");
        PrintMultiDimensionalArray(aSortedUsingDLinqOnJagged);

        Console.Read();
    }

    static void PrintMultiDimensionalArray(IComparable[,] a)
    {
        int rowStart = a.GetLowerBound(0);
        int rowEnd = a.GetUpperBound(0);
        int colStart = a.GetLowerBound(1);
        int colEnd = a.GetUpperBound(1);
        for (int r = rowStart; r <= rowEnd; r++)
        {
            if (colStart != colEnd)
            {
                for (int c = colStart; c < colEnd; c++)
                    Console.Write("{0}, ", a[r, c]);
            }
            Console.WriteLine(a[r, colEnd]);
        }
    }

    static void JaggedArrayToTwoDimensional(IEnumerable<IComparable[]> jagged, ref IComparable[,] a)
    {
        int rowStart = a.GetLowerBound(0);
        int colStart = a.GetLowerBound(1);
        int rowIndex = rowStart;
        foreach (var row in jagged)
        {
            int colIndex = colStart;
            foreach (var val in row)
            {
                a[rowIndex, colIndex++] = val;
            }
            rowIndex++;
        }
    }

    static void ListOfListToTwoDimensionalArray(IEnumerable<List<IComparable>> rows, ref IComparable[,] a)
    {
        int r = 0;
        foreach (var row in rows)
        {
            int c = 0;
            foreach (var val in row)
                a[r, c++] = val;
            r++;
        }
    }

    static void ListOfRowsToTwoDimensionalArray(IEnumerable<Row> rows, ref IComparable[,] a)
    {
        int r = 0;
        foreach (var row in rows)
        {
            int c = 0;
            foreach (var val in row.Values)
                a[r, c++] = val;
            r++;
        }
    }

    static List<Row> TwoDimensionalArrayToListOfRows(IComparable[,] a)
    {
        int rowStart = a.GetLowerBound(0);
        int rowEnd = a.GetUpperBound(0);
        var l = new List<Row>(rowEnd - rowStart + 1);
        for (int r = rowStart; r <= rowEnd; r++)
            l.Add(new Row(a, r));
        return l;
    }

    static List<List<IComparable>> TwoDimensionalArrayToListOfList(IComparable[,] a)
    {
        int rowStart = a.GetLowerBound(0);
        int rowEnd = a.GetUpperBound(0);
        int numRows = rowEnd - rowStart + 1;
        int colStart = a.GetLowerBound(1);
        int colEnd = a.GetUpperBound(1);
        int numCols = colEnd - colStart + 1;
        var l = new List<List<IComparable>>(numRows);
        for (int r = rowStart; r <= rowEnd; r++)
        {
            var row = new List<IComparable>(numCols);
            for (int c = colStart; c <= colEnd; c++)
                row.Add(a[r, c]);
            l.Add(row);
        }
        return l;
    }

    static IComparable[][] TwoDimensionalArrayToJagged(IComparable[,] a)
    {
        int rowStart = a.GetLowerBound(0);
        int rowEnd = a.GetUpperBound(0);
        int numRows = rowEnd - rowStart + 1;
        int colStart = a.GetLowerBound(1);
        int colEnd = a.GetUpperBound(1);
        int numCols = colEnd - colStart + 1;

        var jagged = new IComparable[numRows][];
        for (int r = rowStart; r <= rowEnd; r++)
        {
            int rowIndex = r - rowStart;
            jagged[rowIndex] = new IComparable[numCols];
            for (int c = colStart; c <= colEnd; c++)
                jagged[rowIndex][c - colStart] = a[r, c];
        }

        return jagged;
    }

    public class Row
    {
        public Row(IComparable[,] a, int rowIndex)
        {
            int colStart = a.GetLowerBound(1);
            int colEnd = a.GetUpperBound(1);
            Values = new IComparable[colEnd - colStart + 1];

            for (int c = colStart; c <= colEnd; c++)
                Values[c - colStart] = a[rowIndex, c];
        }
        public IComparable[] Values { get; private set; }
    }
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Linq.Dynamic;
命名空间多维数组排序
{
班级计划
{
静态void Main(字符串[]参数)
{
var testArray=新的可比较[,]{
{1,“a”,新的日期时间(2000,1,1)},
{2,“a”,新的日期时间(2000,1,2)},
{1,“c”,新的日期时间(2000,1,1)},
{5,“a”,新的日期时间(2000,1,1)},
{2,“a”,新的日期时间(2000,1,1)},
};
int numRows=testArray.GetLength(0);
int numCols=testArray.GetLength(1);
var listOfRows=二维数组listOfRows(testArray);
var aSortedUsingLinqOnListOfRows=新的IComparable[numRows,numCols];
var sortedByLinqOnListOfRows=listOfRows.AsParallel().OrderBy(r=>r.Values[0])。然后ByDescending(r=>r.Values[2])。然后By(r=>r.Values[1]);
RowstofWo维度数组列表(分类为BylinqonListoFrows,参考aSortedUsingLinqOnListOfRows);
Console.WriteLine(“\n自定义类型列表中的INQ:”);
打印多维阵列(aSortedUsingLinqOnListOfRows);
var aSortedUsingDLinqOnListOfRows=新的IComparable[numRows,numCols];
var sortedByDLinqOnListOfRows=listOfRows.AsParallel().OrderBy(“值[0]ASC,值[2]DESC,值[1]ASC”);
维度阵列的Rowstof列表(分类为YDLINQONLISTOFROWS,参考ASORTDUSINGDLINQONLISTOFROWS);
Console.WriteLine(“\n\nDLinq在自定义类型的列表上:”);
打印多维阵列(ASORTDUSINGDLINQONLISTOFROWS);
var listOfList=二维数组listOfList(testArray);
var aSortedUsingLinqOnListOfList=新的IComparable[numRows,numCols];
var sortedByLinqOnListOfList=listOfList.AsParallel().OrderBy(r=>r[0])。然后按降序(r=>r[2])。然后按降序(r=>r[1]);
维度数组列表(按列QONLISTOFLIST排序,参考列aSortedUsingLinqOnListOfList);
Console.WriteLine(“\n\n列表中的INQ:”);
打印多维数组(aSortedUsingLinqOnListOfList);
var aSortedUsingDLinqOnListOfList=新的IComparable[numRows,numCols];
var sortedByDLinqOnListOfList=listOfList.AsParallel().OrderBy(“0 ASC,2 DESC,1 ASC”);//此处提供的字符串不正确
二维数组列表(分类为YDLINQONLISTFLIST,参考ASORTDUSINGDLINQONLISTFLIST);
Console.WriteLine(“\n\nDLinq在列表的列表上(不正确):”;
打印多维数组(asortedusingdlinqonlinlistoflist);
var jaggedArray=二维阵列Jagged(测试阵列);
var aSortedUsingLinqOnJagged=新的可比较的[numRows,numCols];
var sortedJaggedLinq=jaggedArray.AsParallel().OrderBy(r=>r[0])。然后依次递减(r=>r[2])。然后依次递减(r=>r[1]);
JaggedarraytoWoDimensional(分类标记,参考aSortedUsingLinqOnJagged);
Console.WriteLine(“\n\n锯齿数组上的inq:”);
打印多维阵列(aSortedUsingLinqOnJagged);
var aSortedUsingDLinqOnJagged=新的可比较的[numRows,numCols];
var sortedUsingDLinqOnJagged=jaggedArray.AsParallel().OrderBy(“0 ASC,2 DESC,1 ASC”);//此处提供的字符串不正确
JAGGEDARRAYTOWO尺寸(已分类,参考aSortedUsingDLinqOnJagged);
Console.WriteLine(“\n\nDLinq在锯齿数组上(不正确):”;
打印多维阵列(aSortedUsingDLinqOnJagged);
Console.Read();
}
静态空打印多维阵列(i可比较[,]a)
{
int rowStart=a.GetLowerBound(0);
int rowEnd=a.GetUpperBound(0);
int colStart=a.GetLowerBound(1);
int colEnd=a.GetUpperBound(1);

对于(int r=rowStart;r我发现了,您应该使用这里定义的关键字“it”:

因此,本例中的排序字符串是:“it[0]ASC,it[2]DESC,it[1]ASC”

看看锯齿数组方法在大数据集上的速度有多快会很有趣。我怀疑它会比使用DataTable快得多