英文:
Trying to append an array value inside a Dictionary<string,string[]>
问题
对于某种原因,我无法将字符串变量附加到Dictionary<string, string[]>中的string[]值。
我正在尝试创建一个用于练习的C#图类,但遇到了问题:我使用Dictionary<string, string[]> graph
来创建以下结构:
"Node1":[connection1,connection2,connection3]
"Node2":[connection1,connection2,connection3]
"Node3":[connection1,connection2,connection3]
...
我有一个方法来附加连接数组值:
// 来自Graph类
private Dictionary<string, string[]> 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<string, string[]> graph
to make a structure like this:
"Node1":[connection1,connection2,connection3]
"Node2":[connection1,connection2,connection3]
"Node3":[connection1,connection2,connection3]
...
I have a method to append a connections array value:
// from Graph class
private Dictionary<string, string[]> 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 = { "node1", "node2", "node3" };
string[][] Edges = { new[] { "node1", "nodeToEdgeTo" }, new[] { "node2", "nodeToEdgeTo" } };
//nodeToEdgeTo are nodes like "node2" or "node3"
foreach (var i in Edges)
{
g.AddEdge(i[0], i[1]);
}
But as a result i get empty values for some reason:
"Node1":[]
"Node2":[]
"Node3":[]
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<string, List<string>> 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 = "level0 : edge0" }; //Your base node/edge
var edge1 = an Edge() { WhatEverData = "level1 : edge1" };
var edge2 = an Edge() { WhatEverData = "level1 : edge2" };
var edge3 = an Edge() { WhatEverData = "level1 : edge3", Edges = new List<Edge> { an Edge() { WhatEverData = "level2" } } };
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<Edge>? Edges { get; set; }
public Edge AddEdge(Edge toAdd)
{
Edges ??= new List<Edge>();
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:
{
"WhatEverData": "level0 : edge0",
"Edges": [
{ "WhatEverData": "level1 : edge1", "Edges": null },
{ "WhatEverData": "level1 : edge2", "Edges": null },
{
"WhatEverData": "level1 : edge3",
"Edges": [{ "WhatEverData": "level2", "Edges": null }]
}
]
}
Hope it helped"
<details>
<summary>英文:</summary>
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
``` 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<string, List<string>> 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 = "level0 : edge0" }; //Your base node/edge
var edge1 = new Edge() { WhatEverData = "level1 : edge1" };
var edge2 = new Edge() { WhatEverData = "level1 : edge2" };
var edge3 = new Edge() { WhatEverData = "level1 : edge3", Edges = new List<Edge> { new Edge() { WhatEverData = "level2" } } };
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<Edge>? Edges { get; set; }
public Edge AddEdge(Edge toAdd)
{
Edges ??= new List<Edge>();
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:
{
"WhatEverData": "level0 : edge0",
"Edges": [
{ "WhatEverData": "level1 : edge1", "Edges": null },
{ "WhatEverData": "level1 : edge2", "Edges": null },
{
"WhatEverData": "level1 : edge3",
"Edges": [{ "WhatEverData": "level2", "Edges": null }]
}
]
}
Hope it helped
答案2
得分: -1
Instead of an array, you might want a List instead: Dictionary<string, List<string>>
.
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<string, List<string>>
.
Then you could do this:
public void AddEdge(string NodeName, string EdgeName)
{
graph[NodeName].Add(EdgeName);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论