gpt4 book ai didi

C# - 在 Foreach 循环中重用变量

转载 作者:行者123 更新时间:2023-11-30 19:38:12 25 4
gpt4 key购买 nike

我想做的是在 List 中找到连续数字组(Excel 行号),并针对每个连续数字 block ,整体 删除行,而不是一次一个,因为有时我会迭代多达 9K 行并不断增长。我遇到的问题是我调整 foreach 循环的方式,我需要重用最后检查的非连续变量。

例如:列表是行 {23,22,21,17,16,15} 我需要拉出 23-21,然后是 17-15,然后删除 block (这就是为什么它们按降序排列,自下而上工作)。循环在 17 处进入 != if 语句并运行,但是 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
}
}
}

希望这很清楚,我花了一些时间才弄清楚如何简明扼要地解释我的需要。谢谢。

最佳答案

我们有什么?一个整数序列。

我们想要什么?一系列整数范围。

首先在类型系统中表示它。我们有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;
}
}

简单。我们方法的签名是什么?我们想要整数和范围,所以:

static class MyExtensions 
{
public static IEnumerable<MyRange> DescendingChunks(this IEnumerable<int> items)

似乎有道理。现在这东西有什么作用?有三种情况。要么我们根本没有范围,因为我们是第一个,要么我们正在扩展当前范围,要么我们有一个新范围。所以每个一个案例:

{
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;
}
}

而且我们从未放弃序列中的最后一件事......

    yield return new MyRange(high, low);
}

有道理吗?现在代替你的循环

foreach (int x in rowsToDelete)

我们有

foreach(MyRange range in rowsToDelete.DescendingChunks())

现在您知道要修改的范围了。

super 加分问题:还有一种情况我没有列举,结果这个方法有个小bug。这是什么?

关于C# - 在 Foreach 循环中重用变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34417933/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com