9

サイトの URL のリストがあり、

  • /node1
  • /node1/sub-node1
  • /node2
  • /node2/sub-node1

リストはランダムな順序で提供されます。最上位が最初で、次にサブレベルが続くように並べる必要があります (存在しないと作成できないため/node2/sub-node1) /node2。これを行うためのきれいな方法はありますか?

今、私は再帰呼び出しを行っているだけで、存在するsub-node1ために作成できない場合は create と言っています。リストの順序で作成を決定し、再帰呼び出しを取り除きたいと思います。node2node2

4

7 に答える 7

6

私の最初の考えは、文字列の長さによる順序付けでした...しかし、次のようなリストを考えました。これには、短い名前のエイリアスのようなものが含まれる可能性があります。

/ロングサイト名/  
/a  
/a/b/c/  
/a  
/a/b/  
/otherlongsitename/  

...そして、最初にレベル区切り文字の数で注文するのがより良いオプションだと思いました:

IEnumerable<string> SortURLs(IEnumerable<string> urls)
{
    return urls.OrderBy(s => s.Count(c => c == '/')).ThenBy(s => s);
}

それから私はそれについてもう少し考えました、そして私はあなたの質問にこの行を見ました:

/node2 が存在しないと /node2/sub-node1 を作成できません

あはは!子が常に親の後にリストされている限り、セクションの順序またはセクション内の順序は重要ではありません。それを念頭に置いて、私の最初の考えは大丈夫で、文字列の長さだけで並べ替えても問題ありません。

IEnumerable<string> SortURLs(IEnumerable<string> urls)
{
    return urls.OrderBy(s => s.Length);
}

なぜ私が長さを気にしたのか、ついに疑問に思ったのはなぜですか?文字列を並べ替えるだけでは、長さに関係なく、先頭が同じ文字列は常に短い文字列が最初に並べ替えられます。したがって、最後に:

IEnumerable<string> SortURLs(IEnumerable<string> urls)
{
    return urls.OrderBy(s => s);
}

将来のある時点で、より字句的または論理的な並べ替え順序が必要になった場合に役立つ可能性があるため、最初のサンプルは残しておきます。

于 2013-06-14T16:13:20.530 に答える
2

これを行うためのきれいな方法はありますか?

標準の文字列ソートを使用して URI のリストをソートするだけで、必要なものが得られます。一般に、文字列ソートでは「a」は「aa」の前に並べられるため、「/node1」は「/node1/sub-node」の前に配置する必要があります。

例えば:

List<string> test = new List<string> { "/node1/sub-node1", "/node2/sub-node1", "/node1",  "/node2"  };

foreach(var uri in test.OrderBy(s => s))
   Console.WriteLine(uri);

これは印刷されます:

/node1
/node1/sub-node1
/node2
/node2/sub-node1
于 2013-06-14T16:09:24.830 に答える
2

おそらくこれはあなたのために働く:

var nodes = new[] { "/node1", "/node1/sub-node1", "/node2", "/node2/sub-node1" };
var orderedNodes = nodes
    .Select(n => new { Levels = Path.GetFullPath(n).Split('\\').Length, Node = n })
    .OrderBy(p => p.Levels).ThenBy(p => p.Node);

結果:

foreach(var nodeInfo in orderedNodes)
{
    Console.WriteLine("Path:{0} Depth:{1}", nodeInfo.Node, nodeInfo.Levels);
}

Path:/node1 Depth:2
Path:/node2 Depth:2
Path:/node1/sub-node1 Depth:3
Path:/node2/sub-node1 Depth:3
于 2013-06-14T16:14:26.200 に答える
0
var values = new string[]{"/node1", "/node1/sub-node1" ,"/node2", "/node2/sub-node1"};
foreach(var val in values.OrderBy(e => e))
{
    Console.WriteLine(val);
}
于 2013-06-14T16:15:07.490 に答える
0

すべての第 2 レベル ノードの前にすべての第 1 レベル ノードが必要な場合は、スラッシュの数で並べ替えます/

string[] array = {"/node1","/node1/sub-node1", "/node2", "/node2/sub-node1"};

array = array.OrderBy(s => s.Count(c => c == '/')).ToArray();

foreach(string s in array)
    System.Console.WriteLine(s);

結果:

/node1
/node2
/node1/sub-node1
/node2/sub-node1

子ノードの前に親ノードが必要なだけの場合、それはそれほど単純ではありません

Array.Sort(array);

結果:

/node1
/node1/sub-node1
/node2
/node2/sub-node1
于 2013-06-14T16:11:30.273 に答える
0

文字列は文字列と数値が混在しているため、自然な並べ替えを使用するのが最善です。他のソート方法またはテクニックを使用していて、次の例のようになっている場合:

List<string> test = new List<string> { "/node1/sub-node1" ,"/node13","/node10","/node2/sub-node1", "/node1", "/node2" };

出力は次のようになります。

/node1
/node1/sub-node1
/node10
/node13
/node2
/node2/sub-node1

ソートされていません。

この実装を見ることができます

于 2013-06-14T16:44:43.577 に答える