尝试将一个数组值附加到 Dictionary<string, string[]> 中。

huangapple go评论60阅读模式
英文:

Trying to append an array value inside a Dictionary<string,string[]>

问题

对于某种原因,我无法将字符串变量附加到Dictionary<string, string[]>中的string[]值。

我正在尝试创建一个用于练习的C#图类,但遇到了问题:我使用Dictionary&lt;string, string[]&gt; graph来创建以下结构:

"Node1":[connection1,connection2,connection3]
"Node2":[connection1,connection2,connection3]
"Node3":[connection1,connection2,connection3]
...

我有一个方法来附加连接数组值:

// 来自Graph类
private Dictionary&lt;string, string[]&gt; graph;

public void AddEdge(string NodeName, string EdgeName)
{
    graph[NodeName].Append(EdgeName);
}

并且像这样使用它:

// 来自Main
Graph g = new Graph();
string[] Nodes = { "node1", "node2", "node3" };
string[][] Edges = { new[] { "node1", "nodeToEdgeTo" }, new[] { "node2", "nodeToEdgeTo" } };
// nodeToEdgeTo 是像 "node2" 或 "node3" 这样的节点

foreach (var i in Edges)
{
    g.AddEdge(i[0], i[1]);
}

但是结果是某种原因为空值:

"Node1":[]
"Node2":[]
"Node3":[]

我不知道为什么。

英文:

For some reason I cannot append a string variable to string[] value in Dictionary<string;string[]>

I am trying to make a Graph C# class for practice and i ran into a problem: I use Dictionary&lt;string, string[]&gt; graph to make a structure like this:

&quot;Node1&quot;:[connection1,connection2,connection3]
&quot;Node2&quot;:[connection1,connection2,connection3]
&quot;Node3&quot;:[connection1,connection2,connection3]
...

I have a method to append a connections array value:

// from Graph class
private Dictionary&lt;string, string[]&gt; graph;

public void AddEdge(string NodeName, string EdgeName)
{
    graph[NodeName].Append(EdgeName);
}

And use it like this:

//from Main
Graph g = new Graph();
string[] Nodes = { &quot;node1&quot;, &quot;node2&quot;, &quot;node3&quot; };
string[][] Edges = { new[] { &quot;node1&quot;, &quot;nodeToEdgeTo&quot; }, new[] { &quot;node2&quot;, &quot;nodeToEdgeTo&quot; } }; 
//nodeToEdgeTo are nodes like &quot;node2&quot; or &quot;node3&quot;

foreach (var i in Edges)
{
    g.AddEdge(i[0], i[1]);
}

But as a result i get empty values for some reason:

&quot;Node1&quot;:[]
&quot;Node2&quot;:[]
&quot;Node3&quot;:[]

I have no idea why

答案1

得分: 0

以下是您要翻译的内容:

"As people already said, an array (as in most languages) are not resizeables.
I think it's interesting to see how you instanciate an array in C to understand that.
In C either you instanciate like that

int[5] myArray

or you choose the dynamic way with malloc pretty much like so

int *myArray = malloc(5 *sizeof(int));

What you can see is that when you instanciate them you have to give it a size and it will "lock" a chunck of memory for it.
Now if you want to add more things to it you have to recreate a new one bigger and copy the content from one to another.

Lists work in a different way. each element of a list are alocated separatly and each of them contain a pointer to the next element.
That's why it's way easier to add an element to a list. What happens under the hood is that it creates that element and alocate memory for it and make the last (or first it depends) element of the list to it (you can see it as a chain)

It should remind you of what you're trying to achieve with your tree. Graphs and lists aren't much different but graph doesn't already exist int c# so you have to recreate it.

Simple answer

So the easy solution for you case is to swap the array by a list like so:

Dictionary&lt;string, List&lt;string&gt;&gt; graph

and then you use it like so

public void AddEdge(string NodeName, string EdgeName)
{
    graph[NodeName].Add(EdgeName);
}

More complicated answer

So following what we said about list, we should assume that each element of your graph should reference other elements.
That will look like so:

using System.Text.Json;

var edge0 = new Edge() { WhatEverData = &quot;level0 : edge0&quot; }; //Your base node/edge


var edge1 = an Edge() { WhatEverData = &quot;level1 : edge1&quot; };
var edge2 = an Edge() { WhatEverData = &quot;level1 : edge2&quot; };
var edge3 = an Edge() { WhatEverData = &quot;level1 : edge3&quot;, Edges = new List&lt;Edge&gt; { an Edge() { WhatEverData = &quot;level2&quot; } } };

edge0.AddEdge(edge1);
edge0.AddEdge(edge2);
edge0.AddEdge(edge3);

Console.WriteLine(JsonSerializer.Serialize(edge0));
public sealed class Edge
{
    public string? WhatEverData { get; set; }
    public List&lt;Edge&gt;? Edges { get; set; }

    public Edge AddEdge(Edge toAdd)
    {
        Edges ??= new List&lt;Edge&gt;();
        Edges.Add(toAdd);
        return this;
    }
}

In this example everything is an edge, Edge0 being the root of your graph but your root could also be a list of edge if you really want to.
The point is that now that it's an object you can put pretty much everything you want in there.
You can also easily serialize it! Here it's what the output of this tiny code looks like:

{
  &quot;WhatEverData&quot;: &quot;level0 : edge0&quot;,
  &quot;Edges&quot;: [
    { &quot;WhatEverData&quot;: &quot;level1 : edge1&quot;, &quot;Edges&quot;: null },
    { &quot;WhatEverData&quot;: &quot;level1 : edge2&quot;, &quot;Edges&quot;: null },
    {
      &quot;WhatEverData&quot;: &quot;level1 : edge3&quot;,
      &quot;Edges&quot;: [{ &quot;WhatEverData&quot;: &quot;level2&quot;, &quot;Edges&quot;: null }]
    }
  ]
}
Hope it helped"

<details>
<summary>英文:</summary>

As people already said, an array (as in most languages) are not resizeables.
I think it&#39;s interesting to see how you instanciate an array in C to understand that.
In C either you instanciate like that
``` C
int[5] myArray

or you choose the dynamic way with malloc pretty much like so

int *myArray = malloc(5 *sizeof(int));

What you can see is that when you instanciate them you have to give it a size and it will "lock" a chunck of memory for it.
Now if you want to add more things to it you have to recreate a new one bigger and copy the content from one to another.

Lists work in a different way. each element of a list are alocated separatly and each of them contain a pointer to the next element.
That's why it's way easier to add an element to a list. What happens under the hood is that it creates that element and alocate memory for it and make the last (or first it depends) element of the list to it (you can see it as a chain)

It should remind you of what you're trying to achieve with your tree. Graphs and lists aren't much different but graph doesn't already exist int c# so you have to recreate it.

Simple answer

So the easy solution for you case is to swap the array by a list like so:

Dictionary&lt;string, List&lt;string&gt;&gt; graph

and then you use it like so

public void AddEdge(string NodeName, string EdgeName)
{
    graph[NodeName].Add(EdgeName);
}

More complicated answer

So following what we said about list, we should assume that each element of your graph should reference other elements.
That will look like so:

using System.Text.Json;

var edge0 = new Edge() { WhatEverData = &quot;level0 : edge0&quot; }; //Your base node/edge


var edge1 = new Edge() { WhatEverData = &quot;level1 : edge1&quot; };
var edge2 = new Edge() { WhatEverData = &quot;level1 : edge2&quot; };
var edge3 = new Edge() { WhatEverData = &quot;level1 : edge3&quot;, Edges = new List&lt;Edge&gt; { new Edge() { WhatEverData = &quot;level2&quot; } } };

edge0.AddEdge(edge1);
edge0.AddEdge(edge2);
edge0.AddEdge(edge3);

Console.WriteLine(JsonSerializer.Serialize(edge0));
public sealed class Edge
{
    public string? WhatEverData { get; set; }
    public List&lt;Edge&gt;? Edges { get; set; }

    public Edge AddEdge(Edge toAdd)
    {
        Edges ??= new List&lt;Edge&gt;();
        Edges.Add(toAdd);
        return this;
    }
}

In this example everything is an edge, Edge0 being the root of your graph but your root could also be a list of edge if you really want to.
The point is that now that it's an object you can put pretty much everything you want in there.
You can also easily serialize it! Here it's what the output of this tiny code looks like:

{
  &quot;WhatEverData&quot;: &quot;level0 : edge0&quot;,
  &quot;Edges&quot;: [
    { &quot;WhatEverData&quot;: &quot;level1 : edge1&quot;, &quot;Edges&quot;: null },
    { &quot;WhatEverData&quot;: &quot;level1 : edge2&quot;, &quot;Edges&quot;: null },
    {
      &quot;WhatEverData&quot;: &quot;level1 : edge3&quot;,
      &quot;Edges&quot;: [{ &quot;WhatEverData&quot;: &quot;level2&quot;, &quot;Edges&quot;: null }]
    }
  ]
}

Hope it helped

答案2

得分: -1

Instead of an array, you might want a List instead: Dictionary&lt;string, List&lt;string&gt;&gt;.

Then you could do this:

public void AddEdge(string NodeName, string EdgeName)
{
    graph[NodeName].Add(EdgeName);
}
英文:

Instead of an array, you might want a List isntead: Dictionary&lt;string, List&lt;string&gt;&gt;.

Then you could do this:

public void AddEdge(string NodeName, string EdgeName)
{
    graph[NodeName].Add(EdgeName);
}

huangapple
  • 本文由 发表于 2023年2月9日 00:26:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75388801.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定