C# 字典,多维数组或交错数组
我有这个字符串:C# 字典,多维数组或交错数组,c#,arrays,dictionary,C#,Arrays,Dictionary,我有这个字符串: string Text = "{1}[56](17)(20)(13)(14)[895](11)(20)[3](8)(12)(3)[19](1)(2)(13)(7)(6)"; 我必须归还这个: Array ( [Type] => 1 [Items] => Array ( [56] => Array ( [1] => 17
string Text = "{1}[56](17)(20)(13)(14)[895](11)(20)[3](8)(12)(3)[19](1)(2)(13)(7)(6)";
我必须归还这个:
Array ( [Type] => 1
[Items] => Array ( [56] => Array ( [1] => 17
[2] => 20
[3] => 13
[4] => 14 )
[895] => Array ( [1] => 11
[2] => 20 )
[3] => Array ( [1] => 8
[2] => 12
[3] => 3 )
[19] => Array ( [1] => 1
[2] => 2
[3] => 13
[4] => 7
[5] => 6 )
)
)
我怎么做这个?我在php中取得了成功,但在c中我找不到解决方案。我先用字典试过,但就是够不着。我只是不知道如何用一个键值多的字典,它也有多个值。到目前为止,我做到了:
var Menu_Matrix = new Dictionary<string, string>();
var Menu_Items = new Dictionary<string, List<string>>();
char[] sep1 = { '{', '}' };
char[] sep2 = { '[', ']' };
char[] sep3 = { '(', ')' };
string[] Menu_Id = new string [10];
string[] Category_Id = new string[20];
Menu_Id = Text.Split(sep1);
Menu_Matrix.Add("Type", Menu_Id[1]);
Category_Id = Menu_Id[2].Split(sep2);
int cat_len = 0;
cat_len = Category_Id.Length;
for (int i = 1; i < cat_len;i++)
{ int pos = 0;
if(Category_Id[i+1].IndexOf('(')!=-1)
pos=i+1;
if(pos>i)
{ var item = new List<string>();
string[] Item_id = new string[20];
Item_id = Category_Id[pos].Split(sep3);
for (int j = 1; j < Item_id.Length;j++ )
if(Item_id[j]!="")
item.Add(Item_id[j]);
Menu_Items.Add(Category_Id[i], item);
}
i = pos;
}
}
return Menu_Items;
希望你知道我想说什么,请帮帮我!我不在乎我用什么:字典,锯齿数组或多维数组。 你可以考虑这样的事情:
string text = "{1}[56](17)(20)(13)(14)[895](11)(20)[3](8)(12)(3)[19](1)(2)(13)(7)(6)";
string[] tokens = text.Split(new Char[] { '}', ']', ')' });
char symbol;
int value;
Dictionary<int, Dictionary<int, List<int>>> data = new Dictionary<int, Dictionary<int, List<int>>>();
Dictionary<int, List<int>> items = null;
List<int> leaves = null;
foreach (string token in tokens) {
if (token.Length == 0) break;
symbol = token[0];
value = Int32.Parse(token.Substring(1));
switch (symbol) {
case '{':
items = new Dictionary<int, List<int>>();
data.Add(value, items);
break;
case '[':
leaves = new List<int>();
items.Add(value, leaves);
break;
case '(':
leaves.Add(value);
break;
}
}
foreach (int type in data.Keys)
{
Console.WriteLine("Type => {{{0}}}", type);
Console.WriteLine("\tItems =>");
items = data[type];
foreach (int item in items.Keys)
{
Console.WriteLine("\t\t[{0}] =>", item);
leaves = items[item];
for (int i = 0; i < leaves.Count; i += 1) {
Console.WriteLine("\t\t\t[{0}] => ({1})", i, leaves[i]);
}
}
}
下面是它的工作原理:
将结束标记上的所有数字拆分为大括号、方括号或圆括号。这将创建一个类似{{1,[56,17,…,6,}的数组
为数据结构的每个级别创建一个变量,该变量表示层次结构中该深度的最后一个对象
如果我们在最后一个空白的令牌上,就早点退出
迭代拆分标记,并将表示数据结构层次结构级别的开始标记保存为符号,将数值保存为值
对于每个符号,采取适当的操作
注意:这段代码强烈要求输入字符串格式正确。例如,如果您传入字符串{1}17,则所有内容都会爆炸,因为没有中间[56]出现的目的是用代码希望已经实例化的新列表填充leaves变量。我认为字典是存储此信息的好结构
外部字典的键是{}的值
内部字典的关键是[]的值
内部字典中列表中的值将是的值,但不带括号
为了解析出这些信息,我认为使用Regex.Splits组合来获得外部键和内部键,以及使用Regex.Match来获得内部键的值是一种很好的方法
代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string Text = "{1}[56](17)(20)(13)(14)[895](11)(20)[3](8)(12)(3)[19](1)(2)(13)(7)(6){2}[99](1)(2)(3)";
// Split out pairs
// 0: {#}
// 1: [#](#)..(n)
string[] splits = Regex.Split(Text, "({\\d+})").Where(split => !String.IsNullOrEmpty(split)).ToArray();
Dictionary<string, Dictionary<string, List<int>>> items = new Dictionary<string, Dictionary<string, List<int>>>();
for (int i = 0; i < splits.Length; i += 2)
{
// splits[i] is {#} which will make the key for this part of the Dictionary
items.Add(splits[i], new Dictionary<string, List<int>>());
items[splits[i]] = new Dictionary<string, List<int>>();
// Split out sub pairs
// 0: [#]
// 1: (#)..(n)
string[] subSplits = Regex.Split(splits[i + 1], "(\\[\\d+\\])").Where(subSplit => !String.IsNullOrEmpty(subSplit)).ToArray();
for (int j = 0; j < subSplits.Length; j += 2)
{
// subSplits[j] is [#] which will make the key for the inner Dictionary
items[splits[i]].Add(subSplits[j], new List<int>());
// subSplits[j + 1] is all of the (#) for each [#]
// which we'll add to the List of the inner Dictionary
Match m = Regex.Match(subSplits[j + 1], "(\\d+)");
while (m.Success)
{
items[splits[i]][subSplits[j]].Add(Convert.ToInt32(m.Groups[0].ToString()));
m = m.NextMatch();
}
}
}
// Print the keys of the Dictionary, the keys of the inner Dictionary, the values of the inner Dictionary
foreach (string key in items.Keys)
{
Console.WriteLine("Key: {0}", key);
foreach (string subKey in items[key].Keys)
{
Console.WriteLine("\t SubKey: {0}", subKey);
Console.WriteLine("\t\t Value: {0}", String.Join(", ", items[key][subKey]));
}
}
}
}
请参阅此处的工作示例…您说过您在PHP中尝试了一些东西,也许可以向我们展示一下,这样我们就可以帮助您了?要使同一个键的多个值适合字典,请使用字典。您可以共享您希望最终结果是什么样的吗?好的。这是我在PHP中的代码,它返回了我想要的矩阵。结果如下所示:数组[类型]=>1[项目]=>Array[56]=>Array[1]=>17[2]=>20[3]=>13[4]=>14[895]=>Array[1]=>11[2]=>20[3]=>Array[1]=>8[2]=>12[3]=>3等等,谢谢你的回答!你的解决方案很好,但它不处理异常。我不知道为什么我不考虑字典中的字典。所以我用你的IDEA修改了我的代码,它工作了!!!再次感谢。@Nicoletserban你想让它处理什么异常?任何解析算法都将依赖于数据中的数据正确的格式。@NicoletaSerban如果您提到您的代码正在工作,如果您发现我的答案对您的问题有帮助,请单击我的答案的复选标记,这样您的问题就可以解决了:-值得一提的是,我认为当您可以只进行基于单个字符串的拆分时,使用两个正则表达式拆分和一个正则表达式匹配会增加复杂性并降低执行效率我在回答中使用的结构越扁平,就越容易理解。谢谢你的回答。
Type => {1}
Items =>
[56] =>
[0] => (17)
[1] => (20)
[2] => (13)
[3] => (14)
[895] =>
[0] => (11)
[1] => (20)
[3] =>
[0] => (8)
[1] => (12)
[2] => (3)
[19] =>
[0] => (1)
[1] => (2)
[2] => (13)
[3] => (7)
[4] => (6)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string Text = "{1}[56](17)(20)(13)(14)[895](11)(20)[3](8)(12)(3)[19](1)(2)(13)(7)(6){2}[99](1)(2)(3)";
// Split out pairs
// 0: {#}
// 1: [#](#)..(n)
string[] splits = Regex.Split(Text, "({\\d+})").Where(split => !String.IsNullOrEmpty(split)).ToArray();
Dictionary<string, Dictionary<string, List<int>>> items = new Dictionary<string, Dictionary<string, List<int>>>();
for (int i = 0; i < splits.Length; i += 2)
{
// splits[i] is {#} which will make the key for this part of the Dictionary
items.Add(splits[i], new Dictionary<string, List<int>>());
items[splits[i]] = new Dictionary<string, List<int>>();
// Split out sub pairs
// 0: [#]
// 1: (#)..(n)
string[] subSplits = Regex.Split(splits[i + 1], "(\\[\\d+\\])").Where(subSplit => !String.IsNullOrEmpty(subSplit)).ToArray();
for (int j = 0; j < subSplits.Length; j += 2)
{
// subSplits[j] is [#] which will make the key for the inner Dictionary
items[splits[i]].Add(subSplits[j], new List<int>());
// subSplits[j + 1] is all of the (#) for each [#]
// which we'll add to the List of the inner Dictionary
Match m = Regex.Match(subSplits[j + 1], "(\\d+)");
while (m.Success)
{
items[splits[i]][subSplits[j]].Add(Convert.ToInt32(m.Groups[0].ToString()));
m = m.NextMatch();
}
}
}
// Print the keys of the Dictionary, the keys of the inner Dictionary, the values of the inner Dictionary
foreach (string key in items.Keys)
{
Console.WriteLine("Key: {0}", key);
foreach (string subKey in items[key].Keys)
{
Console.WriteLine("\t SubKey: {0}", subKey);
Console.WriteLine("\t\t Value: {0}", String.Join(", ", items[key][subKey]));
}
}
}
}
Key: {1}
SubKey: [56]
Value: 17, 20, 13, 14
SubKey: [895]
Value: 11, 20
SubKey: [3]
Value: 8, 12, 3
SubKey: [19]
Value: 1, 2, 13, 7, 6
Key: {2}
SubKey: [99]
Value: 1, 2, 3