リスト (.NET) があり、インデントされたツリー構造を構築する必要があります。リスト内の各項目には、インデントのレベルを示す Position プロパティがあります。最終的な構造は次のようになります。
// (1) 1
// (2) 1-1
// (2) 1-2
// (2) 1-3
// (1) 2
// (2) 2-1
// (3) 2-1-1
// (1) 3
括弧内の数値は、Position プロパティです。特定のレベルの後続の各アイテムには、そのレベルのアイテムのリストでのカウントを示すラベルが必要です。サンプルに示すように、下位の位置レベルにはアウトライン形式のラベルがあります。これらのラベルを正しく生成する必要があることに注意してください。
正直なところ、私はしばらく再帰的な作業を行っていません。それが最善の解決策になると考えていますが、仕事を完了する方法にこだわっています。私はそれを過度に複雑にしているかもしれません。「葉」にたどり着いたら、その項目をリストから削除して戻るべきだと思いますが、よくわかりません。車輪を少し回すだけです。
ありがとう、ジェイ
アップデート:
これに近いものがありますが、最後のケースを理解するのに苦労しています。これまでのところ、次のアイテムが同じレベルにあるか、1 レベル インデントされている場合は問題ありませんが、リスト内の次のアイテムが現在の位置よりも低い位置にある (つまり、さらにインデントされている) 場合のケースが必要です。左)。また、メソッドの上部にある基本ケースについてはわかりません。
var sb = new StringBuilder();
BuildTree(sb, list, 0, 1, string.Empty);
return sb.ToString();
private void BuildTree(StringBuilder sb, List<Item> list, int currIndex, int count, string parentId)
{
if (list.Count == currIndex)
{
return;
}
// Build my item.
string currId = parentId == string.Empty ? count.ToString() : parentId + "-" + count;
sb.Append(currId + "<br />");
if (list[currIndex + 1].Position == list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, count + 1, parentId);
}
if (list[currIndex + 1].Position > list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, 1, currId);
}
}
アップデート:
別の実装ですが、インデントが少ない行の場合はまだ失敗します:
private void BuildTree(StringBuilder sb, List<Item> list, int currIndex, int count, string parentId)
{
if (list.Count == 0)
{
return;
}
// Build my item.
string currId = parentId == string.Empty ? count.ToString() : parentId + "-" + count;
sb.Append(currId + "<br />");
if (list[currIndex + 1].Position == list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, count + 1, parentId);
}
if (list[currIndex + 1].Position > list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, 1, currId);
}
list.RemoveAt(currIndex);
}
アップデート:
これはハックですが、機能します。基本的に、ルートから複数のサブツリーを構築しています。ハックするよりも適切な解決策を望んでいますが、これはこれまでのところ私の最善の試みです。代替案歓迎:
var sb = new StringBuilder();
List<Person> list = GetTheList();
int cnt = 0;
while (list.Count > 0)
{
BuildTree(sb, list, 0, ++cnt, string.Empty);
}
return sb.ToString();
private void BuildTree(StringBuilder sb, List<Person> list, int currIndex, int count, string parentId)
{
// Build my item.
string currId = parentId == string.Empty ? count.ToString() : parentId + "-" + count;
sb.Append(currId + "<br />");
if (list.Count > 1)
{
if (list[currIndex + 1].Position == list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, count + 1, parentId);
}
if (list[currIndex + 1].Position > list[currIndex].Position)
{
BuildTree(sb, list, currIndex + 1, 1, currId);
}
}
list.RemoveAt(currIndex);
}