7

これは本当に簡単なはずですが、うまく機能させることができません...異なる行の2つの列を比較し、それに応じてノードまたはリーフとして配置することで、extjsツリーのリストを作成しようとしています。これは私のサンプルデータです

ListA  ListB  labelName
 NY           Parent1
        NY    Leaf1
 HI           Parent2
 AK           Parent3

これが私のc#の終わりです...したがって、NYと一致する場合、Parent1をノードとして、Leaf1をリーフとして、HIまたはAKではないはずです...しかし、これを行うと、すべてのデータがParentとしてスローされます。葉。

            SqlCommand cmd = con.CreateCommand();

            comd.CommandText = "SELECT * FROM myTable";
            con.Open();
            SqlDataReader reader = comd.ExecuteReader();
            while (reader.Read())
            {
                City MyData = new City();

                MyData.ListA = reader["ListA"].ToString().Trim();
                MyData.ListB = reader["ListB"].ToString().Trim();
                MyData.labelName = reader["labelName"].ToString().Trim();
                giveData.Add(MyData);
            }

            int count = 1;

            List<TreeNode> myNode = new List<TreeNode>();
            foreach (City MyData in giveData)
            {
                // 1st foreach
                    if (MyData.ListA != "")
                    {

                        TreeNode treeNode = new TreeNode();
                        treeNode.id = count++;
                        treeNode.name = MyData.labelName;
                        treeNode.leaf = false;

                        List<TreeNode> Level1 = new List<TreeNode>();
                        foreach (City labelName  in giveData)
                        {
                            if (labelName.ListA == labelName.ListB)
                            {// 2nd foreach
                                TreeNode node1 = new TreeNode();
                                node1.id = count++;
                                node1.name = labelName.labelName;
                                node1.leaf = true;

                                Level1.Add(node1);
                            }
                        }

                        treeNode.children = Level1;
                        myNode.Add(treeNode);
                }
            }
            return JsonConvert.SerializeObject(myNode);

配列を使用して各レコードを保存し、代わりにそれらを比較する必要があります...私はアイデアがありません...これを達成するためのより良い方法があると確信しています...助けてください

4

3 に答える 3

3

データがあなたが述べる方法であり、「親」が葉の前に来ると仮定すると、ツリーを作成するために私が思いついたシングルパスの方法は次のとおりです。

[不適切なコードが切り取られました]

更新:LINQを使用してDictionary<string, List<TreeNode>>

新しいクラスTreeNodeとテスト用のサンプルデータを作成しました。

var MyData = new List<City>
                  {
                     new City {ListA = "AK", ListB = "", labelName = "Alaska"},
                     new City {ListA = "HI", ListB = "", labelName = "Hawaii"},
                     new City {ListA = "", ListB = "HI", labelName = "Hawaii Leaf 1"},
                     new City {ListA = "", ListB = "HI", labelName = "Hawaii Leaf 2"},
                     new City {ListA = "NY", ListB = "", labelName = "New York"},
                     new City {ListA = "", ListB = "NY", labelName = "New York Leaf 1"},
                     new City {ListA = "", ListB = "NY", labelName = "New York Leaf 2"}
                  };

これは、基本的に2つのリストを作成する新しい方法です。1つは親用、もう1つは葉用です。次に、葉をループして一致する親を見つけ、それに葉を追加します。

var index = 0;
var parents = (from p in MyData
               where p.ListB == ""
               select p).ToDictionary(p => p.ListA, p => new TreeNode { id = index++, name = p.labelName, leaf = false });

var leaves = (from l in MyData
              where l.ListA == ""
              group l by l.ListB into stateGroup
              select stateGroup).ToDictionary(g => g.Key, g => g.ToList());

foreach (var leaf in leaves.Where(leaf => parents.ContainsKey(leaf.Key)))
{
    parents[leaf.Key].children =
        leaf.Value.Select(l => new TreeNode {id = index++, name = l.labelName, leaf = true}).ToList();
}

var myNode = parents.Select(p => p.Value).ToList();

return JsonConvert.SerializeObject(myNode);

これはリストやList.Find()

于 2012-12-26T21:56:18.007 に答える
2

あなたの最善の策はおそらくLinqでしょう-私はあなたを正しい方向に動かすために素早く汚いVB.Netソリューションを作成しました-主要な部分は2番目のLinqステートメントです...

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim x As New List(Of City)

    x.Add(New City With {.ListA = "NY", .ListB = "", .Leaf = "Parent1"})
    x.Add(New City With {.ListA = "", .ListB = "NY", .Leaf = "Leaf1"})
    x.Add(New City With {.ListA = "HI", .ListB = "", .Leaf = "Parent2"})
    x.Add(New City With {.ListA = "AK", .ListB = "", .Leaf = "Parent3"})

    tv1.Nodes.AddRange((From y In x Where y.ListA <> "" Select New TreeNode With {
                                                                    .Name = y.ListA,
                                                                    .Text = y.Leaf}).ToArray)

    For Each nd As TreeNode In tv1.Nodes
        Dim Nm As String = nd.Name
        nd.Nodes.AddRange((From y In x Where y.ListB = Nm Select New TreeNode(y.Leaf)).ToArray)
    Next
End Sub

簡単に言うと、親ノードの最初のsteにデータを入力してから、すべてのノードをループして、ListB=ノードの名前である任意のノードをデータに入力します。

これがあなたを正しい方向に動かすのに役立つことを願っています

于 2012-12-26T22:09:59.473 に答える
1

...これをC#で書き込もうとしていますが、これでうまくいくはずです。

        int count = 1;

        List<TreeNode> myNode = new List<TreeNode>();
        foreach (City MyData in giveData)
        {
            // 1st foreach
            if (MyData.ListA != "")
            {

                TreeNode treeNode = new TreeNode();
                treeNode.id = count++;
                treeNode.name = MyData.labelName;
                treeNode.leaf = false;

                foreach (City labelName in giveData)
                {
                    if (MyData.ListA == labelName.ListB)
                    {// 2nd foreach
                        TreeNode node1 = new TreeNode();
                        node1.id = count++;
                        node1.name = labelName.labelName;
                        node1.leaf = true;

                        treeNode.Nodes.Add(node1);
                    }
                }

                myNode.Add(treeNode);
            }
        }
        return JsonConvert.SerializeObject(myNode);

これが少なくともあなたを正しい方向に動かすことを願っています...

于 2012-12-27T13:56:25.073 に答える