C# 如何改进将点分隔字符串转换为数据对象的算法?
我目前正在研究一种算法,将点分隔字符串(Tag1.Tag2.Foo)转换为将在树状视图组件中使用的数据对象。对于字符串的每个部分,如果没有对象,则将创建一个对象。另外,这些对象将与父id“链接在一起”,以便最终数据将显示为树 原始数据: “Tag1.Tag2.Foo”、“Tag1.Tag2.Bar”、“Tag2.Tag3.FooBar”、“Tag3” 转化为:C# 如何改进将点分隔字符串转换为数据对象的算法?,c#,algorithm,C#,Algorithm,我目前正在研究一种算法,将点分隔字符串(Tag1.Tag2.Foo)转换为将在树状视图组件中使用的数据对象。对于字符串的每个部分,如果没有对象,则将创建一个对象。另外,这些对象将与父id“链接在一起”,以便最终数据将显示为树 原始数据: “Tag1.Tag2.Foo”、“Tag1.Tag2.Bar”、“Tag2.Tag3.FooBar”、“Tag3” 转化为: [ { "Id": "ac96e451-b4e4-47f7-afd2-0673b28128d8", "ParentI
[
{
"Id": "ac96e451-b4e4-47f7-afd2-0673b28128d8",
"ParentId": "00000000-0000-0000-0000-000000000000",
"Identifier": "Tag1",
"Text": "Tag1"
},
{
"Id": "e9a86afe-7af5-41e8-a791-11f50a6d472b",
"ParentId": "ac96e451-b4e4-47f7-afd2-0673b28128d8",
"Identifier": "Tag1.Tag2",
"Text": "Tag2"
},
{
"Id": "089403ee-193a-4992-96b7-d69ef9fff957",
"ParentId": "e9a86afe-7af5-41e8-a791-11f50a6d472b",
"Identifier": "Tag1.Tag2.Foo",
"Text": "Foo"
},
{
"Id": "4d806c52-153e-4752-bb9d-f2d187fb11e8",
"ParentId": "e9a86afe-7af5-41e8-a791-11f50a6d472b",
"Identifier": "Tag1.Tag2.Bar",
"Text": "Bar"
},
{
"Id": "c3e1da58-075a-4c8a-9381-316a7b609b87",
"ParentId": "00000000-0000-0000-0000-000000000000",
"Identifier": "Tag2",
"Text": "Tag2"
},
{
"Id": "359c40db-dc12-44e1-b055-d198b568070d",
"ParentId": "c3e1da58-075a-4c8a-9381-316a7b609b87",
"Identifier": "Tag2.Tag3",
"Text": "Tag3"
},
{
"Id": "75418314-bc2c-489f-9319-d57375d4cfec",
"ParentId": "359c40db-dc12-44e1-b055-d198b568070d",
"Identifier": "Tag2.Tag3.FooBar",
"Text": "FooBar"
},
{
"Id": "fd64fe19-7dae-4965-9688-720e7fc210b7",
"ParentId": "00000000-0000-0000-0000-000000000000",
"Identifier": "Tag3",
"Text": "Tag3"
}
]
在树状视图中查看:
-
Tag1
-
Tag2
- 福
- 酒吧
-
Tag2
- Tag2
- Tag3
- FooBar
- Tag3
- Tag3
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace TreeBuilder
{
class Program
{
static void Main(string[] args)
{
var tags = new List<string> { "Tag1.Tag2.Foo", "Tag1.Tag2.Bar", "Tag2.Tag3.FooBar", "Tag3" };
var treeItems = new List<TreeItem>();
foreach (var tag in tags)
{
CreateTreeItems(tag, treeItems);
}
Console.WriteLine(JsonConvert.SerializeObject(treeItems, Formatting.Indented));
}
static void CreateTreeItems(string rawItem, List<TreeItem> treeItems)
{
var rawItems = rawItem.Split('.');
for (int i = 0; i < rawItems.Length; i++)
{
var currentIdentifier = string.Join('.', rawItems.Take(i + 1).ToArray());
// create item if doesnt exist already
if (!treeItems.Any(ti => ti.Identifier == currentIdentifier))
{
var item = new TreeItem
{
Id = Guid.NewGuid(),
ParentId = Guid.Empty,
Text = rawItems[i],
Identifier = currentIdentifier
};
treeItems.Add(item);
// add as child, if necessary
var parentIdentifier = string.Join('.', currentIdentifier.Split('.')[0..(currentIdentifier.Split('.').Length - 1)]);
if (!string.IsNullOrEmpty(parentIdentifier))
{
item.ParentId = treeItems.FirstOrDefault(ti => ti.Identifier == parentIdentifier).Id;
}
}
}
}
}
class TreeItem
{
public Guid Id { get; set; }
public Guid ParentId { get; set; }
public string Identifier { get; set; }
public string Text { get; set; }
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用Newtonsoft.Json;
命名空间树生成器
{
班级计划
{
静态void Main(字符串[]参数)
{
var tags=新列表{“Tag1.Tag2.Foo”、“Tag1.Tag2.Bar”、“Tag2.Tag3.FooBar”、“Tag3”};
var treeItems=新列表();
foreach(标签中的var标签)
{
CreateTreeItems(标记,treeItems);
}
WriteLine(JsonConvert.SerializeObject(treeItems,Formatting.Indented));
}
静态void CreateTreeItems(字符串rawItem、列表treeItems)
{
var rawItems=rawItem.Split('.');
对于(int i=0;iti.Identifier==currentIdentifier))
{
变量项=新树项
{
Id=Guid.NewGuid(),
ParentId=Guid.Empty,
Text=原始项目[i],
标识符=当前标识符
};
添加(项目);
//如有必要,添加为子级
var parentIdentifier=string.Join('.',currentIdentifier.Split('.')[0..(currentIdentifier.Split('.').Length-1)];
如果(!string.IsNullOrEmpty(parentIdentifier))
{
item.ParentId=treeItems.FirstOrDefault(ti=>ti.Identifier==parentIdentifier.Id;
}
}
}
}
}
类树
{
公共Guid Id{get;set;}
公共Guid ParentId{get;set;}
公共字符串标识符{get;set;}
公共字符串文本{get;set;}
}
}
更新
添加了kalexis解决方案中提到的更改。我也删除了这个列表,因为它不再需要了。如果需要列表,可以对字典值使用.toList()
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace TreeBuilder
{
class Program
{
static void Main(string[] args)
{
var tags = new List<string> { "Tag1.Tag2.Foo", "Tag1.Tag2.Bar", "Tag2.Tag3.FooBar", "Tag3" };
var treeItems = new Dictionary<string, TreeItem>();
foreach (var tag in tags)
{
CreateTreeItems(tag, treeItems);
}
Console.WriteLine(JsonConvert.SerializeObject(treeItems, Formatting.Indented));
}
static void CreateTreeItems(string rawItem, List<TreeItem> treeItems)
{
var rawItems = rawItem.Split('.');
for (int i = 0; i < rawItems.Length; i++)
{
var currentIdentifier = string.Join('.', rawItems.Take(i + 1).ToArray());
// create item if doesnt exist already
if (!treeItems.ContainsKey(currentIdentifier))
{
var item = new TreeItem
{
Id = Guid.NewGuid(),
ParentId = Guid.Empty,
Text = rawItems[i],
Identifier = currentIdentifier
};
treeItems[currentIdentifier] = item;
// add as child, if necessary
var parentIdentifier = string.Join('.', currentIdentifier.Split('.')[0..(currentIdentifier.Split('.').Length - 1)]);
if (!string.IsNullOrEmpty(parentIdentifier)
&& treeItems.TryGetValue(parentIdentifier, out var parent))
{
item.ParentId = parent.Id;
}
}
}
}
}
class TreeItem
{
public Guid Id { get; set; }
public Guid ParentId { get; set; }
public string Identifier { get; set; }
public string Text { get; set; }
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用Newtonsoft.Json;
命名空间树生成器
{
班级计划
{
静态void Main(字符串[]参数)
{
var tags=新列表{“Tag1.Tag2.Foo”、“Tag1.Tag2.Bar”、“Tag2.Tag3.FooBar”、“Tag3”};
var treeItems=新字典();
foreach(标签中的var标签)
{
CreateTreeItems(标记,treeItems);
}
WriteLine(JsonConvert.SerializeObject(treeItems,Formatting.Indented));
}
静态void CreateTreeItems(字符串rawItem、列表treeItems)
{
var rawItems=rawItem.Split('.');
对于(int i=0;i
我相信这就是文化原则:
treeItems.Any(ti=>ti.Identifier==currentIdentifier)
treeItems.FirstOrDefault(ti=>ti.Identifier==parentIdentifier)
列表和一个字典,填充两者,并使用Dictionary.ContainsKey()
检查标识符是否正确
Original: 11908.4479ms
With Dictionaries: 32.9763ms