【问题标题】:Finding the length of object array, where value is not-empty查找对象数组的长度,其中值不为空
【发布时间】:2017-07-23 17:19:23
【问题描述】:

我有一个将 Excel 范围输出为object[,] 的方法:

    static public Excel.Workbook OpenWorksheetAsReadOnly(string filePath)
    {
        Excel.Application excelInstance = null;

        // Open workbook as readOnly, update links
        excelInstance = new Excel.Application();
        Excel.Workbook excelWorkbook = excelInstance.Workbooks.
                                       Open(filePath, true, true);

        return excelWorkbook;
    }

static public object[,] ImportExcelIntoArray(string filePath)
    {
        Excel.Workbook source = null;
        source = OpenWorksheetAsReadOnly(filePath);

        Excel.Range sourceRange = source.Sheets[1].Range("B1:D1000");
        object[,] sourceValues = (object[,])sourceRange.Value2;

        return sourceValues;
    }

我知道我的输出数组有 1000 行长。我也知道不是所有这些行都会被填充,而且我知道源文档是从上到下填充的。

在另一种方法中,我想遍历行,但为了节省时间,我只想遍历 实际填充 行的数量。理想情况下,我会使用(其中excelObject 是上述方法的输出):

int rowCount = excelObject.Count(x => x != null);

但是,它不适用于object[*,*] 类型——我认为它适用于List。我看过这里,也看到了excelObject.Length,但这只是给了我对象中的单元格总数。

有没有办法做到这一点?我需要将类型从object 更改为其他类型吗?单元格中的值既是字符串又是浮点数,所以我想尽可能长时间地保留它而不指定类型。

【问题讨论】:

    标签: c# arrays linq


    【解决方案1】:

    由于二维数组实现了非泛型IEnumerable 接口,您可以使用Enumerable.Cast<T> 扩展方法将其转换为IEnumerable<T>,然后对其应用所需的LINQ 运算符:

    int rowCount = excelObject.Cast<object>().Count(x => x != null);
    

    但请注意,上面实际上计算了非空单元格。如果你真的想计算非空,你可以使用Enumerable.Range 在源数组中生成行/列索引:

    var rowCount = Enumerable.Range(0, excelObject.GetLength(0))
        .Count(row => Enumerable.Range(0, excelObject.GetLength(1))
            .Any(col => excelObject[row, col] != null));
    

    【讨论】:

    • 谢谢!只是一个小评论,excelObject 是 1-indexed,所以 Enumerable.Range 的初始参数必须是 1 而不是 0,至少在我的情况下
    猜你喜欢
    • 2023-02-08
    • 2019-05-28
    • 2021-06-10
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    相关资源
    最近更新 更多