在 c# 中不使用 for 循环获取单词 table 的单元格索引的最佳方法是什么?

What is the best way to get cell index of a word table without using for loop in c#?

我正在使用 for 循环获取单词 table 的单元格索引,对于更大的 tables 需要花费大量时间,有没有没有 for 循环的方法?

public static int[] GetColumnIndex(Xceed.Words.NET.Table table, string columnName, int endRow,int k)
        {
            int[] data = { -1, -1 };
            for (int j = k; j < endRow; j++)
            {
                for (int i = 0; i < table.Rows[j].Cells.Count; ++i)
                {
                    if (table.Rows[j].Cells[i].Paragraphs[0].Text.Equals("«" + columnName + "»"))
                    {
                        data[0] = j;
                        data[1] = i;
                        return data;
                    }
                }
            }

            return data;
        }

我从另一个函数调用这个函数

int startRow = 0, endRow = 0;
int[] ind;
DocX doc;
doc = DocX.Load(fileName);
Xceed.Words.NET.Table t;
t = doc.Tables[0];
endRow = t.Rows.Count;
System.Data.DataTable dt = new DataTable();
dt = reader(report.Query);
foreach (DataColumn col in dt.Columns)
{
    ind = GetColumnIndex(t, col.ColumnName, endRow,2);

    //...more code here...
}

为了优化您的算法(基于您的访问模式),您可以做一些事情是搜索相同的 table 次(事实上,因为您正在搜索 table,搜索次数随着 table 变大而迅速增加)。因此,值得将 table 中的数据转换为由单词索引的数据结构(例如 Sorted Dictionary)。

首先,创建一个 class 来保存 table 的内容。这样当你想搜索相同的 table 时,你可以使用 class 的相同实例并避免基于排序字典重新创建数据结构:

public class XceedTableAdapter
{
   private readonly SortedDictionary<string, (int row, int column)> dict;

   public XceedTableAdapter(Xceed.Words.NET.Table table)
   {
      this.dict = new SortedDictionary<string, (int, int)>();
      // Copy the content of the table into the dict.
      // If you have duplicate words you need a SortedDictionary<string, List<(int, int)>> type. This is not clear in your question.
      for (var i = 0, i < rowCount; i++)
      {
          for (var j = 0; j < columnCount; j++)
          {
              // this will overwrite the index if the text was previously found: 
              this.dict[table.Rows[i].Cells[j].Paragraphs[0].Text] = (i, j);
          }
      }
   }

   public (int, int) GetColumnIndex(string searchText)
   {
      if(this.dict.TryGetValue(searchText, out var index))
      {
          return index;
      }

      return (-1, -1);
   }
}

现在您只循环整个 table 一次,随后的搜索将在 O(log n) 中进行。如果 Xceed 有一个将数据 table 转换为字典的功能,那将非常方便。我对这个库不熟悉。

现在您可以像这样搜索:

var searchableTable = new XceedTableAdapter(doc.Tables[0]);

foreach (var col in dt.Columns)
{
   ind = searchableTable.GetColumnIndex(col);
}