仅以C#示例,其他开发语言大同小异。(环境.net8)
除非需要,否则不建议使用迭代函数,写不好容易死循环。
1.计算进度
//有时候在耗时操作中需要同一代码执行多次,每次循环还与上次调用有关,一般JavaScript中用的多
//在某些时候,for或while循环无法确定什么时候该结束时使用这种方法比较好
public class Data
{
public required string Name { get; set; }
public required string Value { get; set; }
}
private static readonly List<Data> datas =
[
new () { Name="测试1",Value = "A" },
new () { Name="测试2",Value = "B" },
new () { Name="测试3",Value = "C" },
new () { Name="测试4",Value = "D" },
new () { Name="测试5",Value = "E" },
new () { Name="测试6",Value = "F" },
new () { Name="测试7",Value = "G" },
new () { Name="测试8",Value = "H" },
];
private int curr = 0;
public async Task Iteration(int i,Action<bool> callback)
{
var data = datas[curr];
Console.WriteLine($"进度{curr}=> Name:{data.Name} Value:{data.Value}");
//耗时操作
await Task.Delay(1000);
//if (err){
// callback.Invoke(false); //出错时执行
//} else {
curr++;
if (curr < datas.Count)
{
await Iteration(curr,callback);
}
else callback?.Invoke(true);
//}
}
public void Run()
{
var waitting = new ManualResetEvent(false);
var _ = Iteration(0, (data) =>
{
Console.WriteLine($"结果:{data}");
waitting.Set();
});
//相当于主线程继续运行
waitting.WaitOne();
Console.WriteLine("执行完成");
waitting.Close();
waitting.Dispose();
}
//Run() 结果:
/**
标准输出:
进度0=> Name:测试1 Value:A
进度1=> Name:测试2 Value:B
进度2=> Name:测试3 Value:C
进度3=> Name:测试4 Value:D
进度4=> Name:测试5 Value:E
进度5=> Name:测试6 Value:F
进度6=> Name:测试7 Value:G
进度7=> Name:测试8 Value:H
结果:True
执行完成
*/
2.树形结构联动处理
//重复次数扩展函数
public static string Repeat(this string target, int count)
{
var sb = new StringBuilder();
for (var i = 0; i < count; i++)
{
sb.Append(target);
}
var res = sb.ToString();
sb.Clear();
return res;
}
////////////////主要代码
public class Node
{
public required int level { get; set; }
//public bool target { get; set; } = false;
//如果是菜单类的话 菜单展开状态
public bool expand { get; set; } = false;
public required string name { get; set; }
public List<Node>? children { get; set; }
//迭代查询
public Node? Query(string nodeName)
{
if (name == nodeName)
{
//赋值状态
//target = true;
expand = true;
return this;
}
if (children == null) return null;
foreach (var node in children)
{
var nd = node.Query(nodeName);
if (nd == null) continue;
/// 示例1 返回最上层(非root,需要返回root的话return this)
else
{
expand = true;
return node;
}
/// 示例2 返回目标层
//else return nd;
/// 示例3 查询上一级
//else if (nd.target)
//{
// //状态置回 不置回的话root关联层级会因为多次查询而出错
// nd.target = false;
// expand = true;
// return this;
//}
//else
//{
// expand = true;
// return nd;
//}
}
return null;
}
//也是个迭代函数
public void Unexpand() //全折叠(懒省事)
{
expand = false;
children?.ForEach(a=>a.Unexpand());
}
public override string ToString()
{
return $"\r\n{"\t".Repeat(level)}name:{name};expand:{expand};children:{(children == null ? "null" : $"[{children?.Select(a => a.ToString()).Aggregate((a, b) => $"{a},{b}")}\r\n{"\t".Repeat(level)}]")}";
}
}
private static Node root = new()
{
level = 0,
name = "0",
children = [
new () { level = 1, name="1",
children = [
new() { level = 2, name="1A" },
new() { level = 2, name = "1B" },
new() { level = 2, name="1C",
children = [
new() { level = 3, name="1C1"},
new() { level = 3, name="1C2" },
new() { level = 3, name = "1C3" }
]}
] },
new () { level = 1, name="2",
children = [
new() { level = 2, name="2A" },
new() { level = 2, name = "2B",
children = [
new() { level = 3, name = "2B1" },
new() { level = 3, name = "2B2" },
new() { level = 3, name = "2B3" }
] },
new() { level = 2, name = "2C" }
] },
new () { level = 1, name="3",
children = [
new() { level = 2, name = "3A",
children = [
new() { level = 3, name = "3A1" },
new() { level = 3, name = "3A2" },
new() { level = 3, name = "3A3" }
] },
new() { level = 2, name = "3A1" },
new() { level = 2, name = "3A2" }
] },
]
};
private void ForQuery(string query)
{
Console.WriteLine($"查找{query}...");
var node = root.Query(query);
Console.WriteLine($"查询结果\t{(node == null ? "null" : node.ToString())}\r\n");
root.Unexpand();//展开状态置回
}
public void Run()
{
ForQuery("3A");
ForQuery("1B");
ForQuery("4C");
ForQuery("3A2");
}
/// 结果
/**
标准输出:
查找3A...
查询结果
name:3;expand:True;children:[
name:3A;expand:True;children:[
name:3A1;expand:False;children:null,
name:3A2;expand:False;children:null,
name:3A3;expand:False;children:null
],
name:3A1;expand:False;children:null,
name:3A2;expand:False;children:null
]
查找1B...
查询结果
name:1;expand:True;children:[
name:1A;expand:False;children:null,
name:1B;expand:True;children:null,
name:1C;expand:False;children:[
name:1C1;expand:False;children:null,
name:1C2;expand:False;children:null,
name:1C3;expand:False;children:null
]
]
查找4C...
查询结果 null
查找3A2...
查询结果
name:3;expand:True;children:[
name:3A;expand:True;children:[
name:3A1;expand:False;children:null,
name:3A2;expand:True;children:null,
name:3A3;expand:False;children:null
],
name:3A1;expand:False;children:null,
name:3A2;expand:False;children:null
]
*/