我想要做的就是找到连续数字(Excel中的行号)中成组List并连续号码中的各个块,删除行集体,而不是一个在时刻,因为有时我会遍历,高达9K行并且在成长.我遇到的问题是我调整foreach循环的方式,我需要重用已检查的最后一个非连续变量.
例如:列表是行{23,22,21,17,16,15}我需要拉出23-21,然后是17-15,然后删除块(这就是为什么它们按降序排列,从自下而上).循环进入!= if17上的语句,然后工作,但是已经使用了17,并且16是循环的下一次迭代,因此17从未被捕获为下一个连续编号分组的开始.
我的问题:有没有办法以这种方式坚持17,以及新连续组的任何其他开始,还是我咆哮错误的树?
码:
public void FindMatchingBlocks(string stateId, string[] rangeNames)
{
Excel.Worksheet wksht = wkbk.Sheets["Sheet1"];
Excel.Range rng = wksht.Range["$A$15:$A$23"];
string val;
string val2;
List<int>rowNums = new List<int>();
string rngStart = rangeNames[0].ToString(); //gives me "$A$15"
string rngEnd = rangeNames[1].ToString();//gives me $A$23$
string[] tempArray = rngEnd.Split('$');
string end = tempArray[2].ToString();
List<int> rowsToDelete = new List<int>();
foreach (Excel.Range range in rng)
{
if (range.Row < Convert.ToInt32(end)+1)
{
//pulls out the first two characters of the cell value to
// match it to the stateID, if they match they are not to
// be added to the list and not be deleted.
val = range.Value.ToString();
val2 = val.Substring(0, 2);
if (Convert.ToInt32(val2) != Convert.ToInt32(stateId))
{
rowsToDelete.Add(range.Row); // ends up being
// {23,22,21,17,16,15}
}
}
}
int count = 0;
int firstItem = 0;
rowsToDelete.Reverse(); //delete from the bottom up
foreach (int x in rowsToDelete)
{
// First value in the ordered list: start of a sequence
if (count == 0)
{
firstItem = x;
count = 1;
}
// Skip duplicate values
else if (x == firstItem - count)
{
count++;
}
// New value contributes to sequence
else if (x != firstItem - count)
{
int endRow = firstItem;
int startRow = firstItem - count + 1;
Excel.Range delRange = wksht.Rows[startRow.ToString() + ":" + endRow.ToString()];
delRange.Delete(Excel.XlDeleteShiftDirection.xlShiftUp);
count = 0;
firstItem = ????; //can I do something to keep the first
//non-consecutive number each time it is
// encountered. In this list it skips 17
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望这很清楚,带我去了解如何简明扼要地解释我需要什么.谢谢.
我们有什么?一系列整数.
我们想要什么?整数范围的序列.
首先在类型系统中表示.我们有IEnumerable<int>一系列整数.让我们做一个小类型:(在这里使用C#6表示法)
struct MyRange
{
public int High { get; }
public int Low { get; }
public MyRange(int high, int low) : this()
{
High = high;
Low = low;
}
}
Run Code Online (Sandbox Code Playgroud)
简单.我们方法的签名是什么?我们想要整数和范围,所以:
static class MyExtensions
{
public static IEnumerable<MyRange> DescendingChunks(this IEnumerable<int> items)
Run Code Online (Sandbox Code Playgroud)
似乎合理.现在这件事做了什么?有三种情况.要么我们没有任何范围,因为我们是第一个,或者我们正在扩展当前范围,或者我们有一个新的范围.每个案例都有一个案例:
{
bool first = true;
int high = 0;
int low = 0;
foreach(int item in items)
{
if (first)
{
high = item;
low = item;
first = false;
}
else if (item == low - 1)
{
low = item;
}
else
{
yield return new MyRange(high, low);
high = item;
low = item;
}
}
Run Code Online (Sandbox Code Playgroud)
而且我们从未在序列中产生最后的东西......
yield return new MyRange(high, low);
}
Run Code Online (Sandbox Code Playgroud)
合理?而不是你的循环
foreach (int x in rowsToDelete)
Run Code Online (Sandbox Code Playgroud)
我们有
foreach(MyRange range in rowsToDelete.DescendingChunks())
Run Code Online (Sandbox Code Playgroud)
现在您知道要修改的范围.
超级红利问题:还有一个我没有列举的案例,因此这个方法存在一个小错误.它是什么?
| 归档时间: |
|
| 查看次数: |
811 次 |
| 最近记录: |