查找 IEnumerable 的第一个索引

Find First Index of IEnumerable

我有一个接受 IEnumerable 作为参数的方法。 我的问题是这个方法有时会给出一个从 1(而不是 0)开始的数组。

我可以只创建一个列表并将参数的元素添加到其中,但是没有办法只获取第一个索引吗?

编辑 1: 我的意思是 "an array that starts at 1" 是一个字面上从 1 开始的数组,例如:

我无法使用以下行访问数组 "cells":

cells[0, 0]

正在从 Excel 范围内读取此特定数组。

编辑 2: 这不是唯一提供给方法的数组。 该方法还接收从 0 开始的数组,它需要适用于所有情况。

我不明白你说的是什么意思。

有时给定一个从 1

开始的数组

数组必须从 零索引开始, 我想你的意思是尝试过滤值并检查是否为 null 空值 您可以尝试以下方法:

var firstValue = array.First(x => !string.IsNullOrWhiteSpace(x.value));

或者您可以删除第一个元素或符合条件的任何元素

array = array.Skip(0);

更新

当您将子数组传递给该方法时,通常它不会从索引零开始。

因此,您可以使用 ElementAtOrDefault() Linq method.

在数组上循环并在检查项目是否存在后处理这些项目
for (int i = 0; i < array.length; i++)
 {
    if(ElementAtOrDefault(i) != null)
        // your logic
 }

根据需要,您可以分别使用。阅读下面的 link。

 var firstValue = Yourlist.First(x => x.value);

var firstValue = Yourlist.FirstOrDefault(x => x.value);

var firstValue = Yourlist.Single(x => x.value);

var firstValue = Yourlist.SingleOrDefault(x => x.value);

LINQ Single vs First

通常数组的下限为 0。但是,您可以创建具有不同下限的数组。为此,您需要使用 Array.CreateInstance:

var array = Array.CreateInstance(typeof(string), new[] { 10 }, new[] { 1 });

这将创建一个包含十个元素且下限为 1 的一维数组。以下是设置第一个元素的值的方法:

array.SetValue("first", 1);

在您的情况下,您可以使用这样的代码创建一个包含 10 x 20 元素和下限 1 的二维数组:

var array = (object[,]) Array.CreateInstance(typeof(object), new[] { 10, 20 }, new[] { 1, 1 });

要获得第一个维度的下限,您可以使用 GetLowerBound:

var lowerBound = array.GetLowerBound(0);

以1为参数,获取第二维的下界等等。还有一个GetUpperBound的方法。如果您甚至不知道数组的维度,您可以检查 Rank 属性.

我相信此功能的存在主要是为了支持将旧的 Visual Basic 代码移植到 Visual Basic .NET 并与 COM 自动化互操作(例如 Excel),其中数组的下限通常为 1。

如果您询问 Excel Interop:

  • 索引器 - 索引器是 1 基:

    cells[1,1].Value2 = "something";
    
  • IEnumerable - 使用 CastFirstFirstOrDefalt:

    cells.Cast<dynamic>().FirstOrDefault().Value2 = "something";
    
  • IEnumerable - 使用 GetEnumerator:

    var enumerator  = cells.GetEnumerator();
    enumerator.MoveNext();
    ((dynamic)enumerator.Current).Value2 = "something";
    
  • 如果您有兴趣了解sheet中的列索引和行索引,ColumnRow属性将显示sheet.

  • 中的坐标

正如@MartinLiversage 指出的那样,Array.CreateInstance 的重载允许指定下限:

public static Array CreateInstance (Type elementType, int[] lengths, int[] lowerBounds);

您必须将不明确的 Array 转换为具体类型,才能直接访问其元素。示例:

var cells =
    (int[,])Array.CreateInstance(typeof(int), new[] { ROWS, COLUMNS }, new[] { 1, 1 }); 

您可以使用 cells.GetLowerBound(0)(第一维)和 cells.GetLowerBound(1)(第二维)获取边界。有相应的GetUpperBound方法。示例:

// Loop through the matrix
for (int i = cells.GetLowerBound(0); i <= cells.GetUpperBound(0); i++) {
    for (int j = cells.GetLowerBound(1); j <= cells.GetUpperBound(1); j++) {
        // Get an element
        var element = cells[i, j];

        // Set an element
        cells[i, j] = value;
    }
}

或者,仅获取第一个元素:

var result = cells[cells.GetLowerBound(0), cells.GetLowerBound(1)];

你也可以用foreach枚举数组。这会使数组变平,即将数组视为一维数组。

请注意,LINQ 扩展方法 First 总是 returns 第一项,而不考虑数组的下限。

var result = cells.First();