我有这个对象:
public class dtHeader
{
public dtHeader ParentHeader { get; set; }
public string HeaderText { get; set; }
public string DataField { get; set; }
public bool Visible { get; set; }
public int DisplayOrder { get; set; }
}
我想用lambda表达式计算,对象的深度,对象本身有多少层?
我看到this JavaScript post,但我正在努力将其转换为单行lambda语句。
让我们说对象就是这个new dtHeader(){ ParentHeader = null, HeaderText = "col1" };
结果将是1
和new dtHeader(){ ParentHeader = new dtHeader(){ ParentHeader = null, HeaderText = "col1" }, HeaderText = "col1" };
结果为2
我希望用list<dtHeader>
实现这一目标,因此其中一些深度为1,其他深度更深,并且需要最深的深度。
_______ITEM_IN_LIST_OBJECT__
______1___2___3___4___5___6_
D 1. |_o_|_o_|_o_|_o_|_o_|_o_|
E 2. |_o_|___|_o_|___|_o_|_o_|
P 3. |___|___|_o_|___|_o_|___|
T 4. |___|___|___|___|_o_|___|
H 5. |___|___|___|___|_o_|___|
它必须无限(直到它允许对象在彼此内部堆积)深。
var HeaderLayerCount = lDtCol.Where(n => n.ParentHeader != null)
.Where(n => n.ParentHeader.ParentHeader != null)
.Where(n => n.ParentHeader.ParentHeader.ParentHeader != null);
修改: 我只想补充一点,如果你想在特定的深度级别上工作,例如深度为3的所有对象,你可以在类中使用这个额外的递归函数
public class dtCol
{
public dtCol ParentHeader { get; set; }
public string HeaderText { get; set; }
public string DataField { get; set; }
public bool Visible { get; set; }
public int DisplayOrder { get; set; }
public int Depth { get { return ParentHeader != null ? ParentHeader.Depth + 1 : 1; } }
public int CurrentDepth { get; set; } //Set on initialisation
public dtCol getParent(dtCol col, int getDepth) //Gets the parent on a specific level after the first base level (1) else returns the previous not null child
{
return (col.ParentHeader != null && col.ParentHeader.CurrentDepth == getDepth) ? col.ParentHeader : this.getParent(col.ParentHeader, getDepth);
}
}
您可以像这样使用它:
var HeaderLayerCount = lDtCol.OrderByDescending(n => n.Depth).First().Depth;
for (int hlc = 1; hlc <= HeaderLayerCount; hlc++)
{
var headerrow = new List<dtCol>();
//This foreach adds the parent header if not null else adds the not null child
lDtCol.ForEach(n =>
{
var h = n.getParent(n, hlc); //Get Parent, null is returned if parent does not exists
headerrow.Add((h != null) ? h : n); //If parent is null, add base dtCol so that the headers can be merged upwards.
});
//Do what you need with your new single dimensional list of objects
}
答案 0 :(得分:4)
为什么不在你的类上实现一个get getDepth()方法,它将达到最高的祖先,计算每个级别?
您的查询会更加简单。
我被弗洛德击败,对他不满
我有相同的实现:
public int GetDepth()
{
if (ParentHeader == null)
{
return 1;
}
else return 1 + ParentHeader.GetDepth();
}
答案 1 :(得分:2)
using System;
using System.Linq;
namespace ConsoleApplication3
{
public class dtHeader
{
public dtHeader ParentHeader { get; set; }
public string HeaderText { get; set; }
public string DataField { get; set; }
public bool Visible { get; set; }
public int DisplayOrder { get; set; }
public int Depth
{
get
{
// If header has parent, then this depth is parent.depth + 1
if (ParentHeader != null)
return ParentHeader.Depth+1;
else
return 1; // No parent, root is depth 1
}
}
}
class Program
{
static void Main(string[] args)
{
dtHeader[] headers = {
new dtHeader { HeaderText = "dt1" },
new dtHeader { HeaderText = "dt2" },
new dtHeader { HeaderText = "dt3" },
new dtHeader { HeaderText = "dt4" },
new dtHeader { HeaderText = "dt5" }
};
headers[1].ParentHeader = headers[0];
headers[2].ParentHeader = headers[1];
headers[3].ParentHeader = headers[2];
headers[4].ParentHeader = headers[3];
var deepest = headers.OrderByDescending(item=>item.Depth).First();
Console.WriteLine(deepest.Depth+ ", " + deepest.HeaderText);
var runner = deepest;
while (runner.ParentHeader != null)
runner = runner.ParentHeader;
Console.WriteLine("The deepest root header is:" + runner.HeaderText);
}
}
}
答案 2 :(得分:2)
这是一个lambda表达式,可以得到你想要的东西:
Func<dtHeader, int> getDepth = null;
getDepth = dth =>
{
var depth = 1;
if (dth.ParentHeader != null)
{
depth += getDepth(dth.ParentHeader);
}
return depth;
};
您必须将其分为两部分(分配null
并指定正文)以使递归工作。
答案 3 :(得分:0)
我修改了Enigmativity的答案,使其正常工作:
Func<dtHeader, int, int> getDepth = null;
getDepth = (dth, depth) =>
{
if (dth.ParentHeader != null)
{
depth = getDepth(dth.ParentHeader, ++depth);
}
return depth;
};
这样称呼:
int depth = getDepth(header, 0)