Operate LINQ queries on 'vertical' rather than 'horizontal' space

前端 未结 3 1513

I can\'t figure out how to do this, if even possible.
An example:

int[][] myArrays = {
    new int[] {1, 2, 3},
    new int[] {4, 5, 3},
    new int[] {1         


        
3条回答
  •  旧巷少年郎
    2020-12-22 11:52

    You didn't specify what you want if the arrays have unequal length:

    int[][] myArrays =
    {
        new int[] {1, 2},
        new int[] {4, 5, 3, 7, 5, 3, 4, 5, 1},
        new int[] {1, 2, 3}
    };
    

    Let's assume your arrays all have the same length.

    If you plan to use this functionality regularly, consider writing an extension function for two dimensional arrays. See Extension Methods Demystified

    public static IEnumerable ToVerticalAverage(this int[][] array2D)
    {
        if (array2D ==  null) throw new ArgumentNullException(nameof(array2D);
    
        // if input empty: return empty
        if (array2D.Any())
        {   // there is at least one row
            // check number of columns:
            int nrOfColumns = array2D.First().Length;
            if (!array2D.All(row => row.Length == nrOfColumns)
            {
               // TODO: decide what to do if arrays have unequal length
            }
    
            // if here, at least one row, all rows have same number of columns
            for(int columNr = 0; columNr < nrOfColumns; ++columNr)
            {
                yield return array2D.Select(row => row[i]).Average();
            }
        }
        // else: no rows, returns empty sequence
    }
    

    Usage:

    int[][] myInputValues = ...
    IEnumerable averageColumnValues = myInputValues.ToVerticalAverage();
    

    If you have several functions where you need the values of the columns, write an extension function to fetch the columns (= transpose the matrix)

    public static IEnumerable> Transpose(this int[][] array2D)
    {
         // TODO: check input
         int nrOfColumns = array2D.First().Length;
         for(int columNr = 0; columNr < nrOfColumns; ++columNr)
         {
              yield return array2D.Select(row => row[columnNr];
         }
    }
    public static IEnumerable ToVerticalAverage(this int[][] array2D)
    {
        // TODO: check input
        foreach (IEnumerable column in array2D.Transpose())
        {
             yield return column.Average();
        }
    

提交回复
热议问题