Создание модели для представления ключа, как это:
Следующий класс представляет часть пути, как /ReturnState[1]
, и он содержит метод (конструктор) для анализа данных из строки и другого метода для преобразования данных в строковый формат.
public class Part
{
public string Name { get; set; }
public int Index { get; set; }
public Part(string str)
{
int location_of_bracket_start = str.LastIndexOf("[");
if(location_of_bracket_start == -1)
throw new Exception("Unexpected format");
Name = str.Substring(0, location_of_bracket_start);
string rest = str.Substring(location_of_bracket_start);
Index = int.Parse(rest.Substring(1, rest.Length - 2));
}
public string ConvertToStringFormat()
{
return string.Format("/{0}[{1}]", Name, Index);
}
}
Следующий класс представляет собой полный путь (например /ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[1]/FormA1[1]
) в виде списка частей. Он также содержит метод построения объекта из строки и преобразования в строку.
public class NodePath : List<Part>
{
public NodePath(string path)
{
string[] parts = path.Split(new []{"/"}, StringSplitOptions.RemoveEmptyEntries);
foreach (string part in parts)
{
this.Add(new Part(part));
}
}
public string ConvertToStringFormat()
{
return string.Join("", this.Select(x => x.ConvertToStringFormat()));
}
}
Следующий класс содержит логику, что вам нужно:
public class PathClass
{
private readonly Dictionary<string, int> m_Dictionary;
public PathClass()
{
m_Dictionary = new Dictionary<string, int>();
}
public Dictionary<string, int> Dictionary
{
get { return m_Dictionary; }
}
public void Add(string path, int number)
{
if (m_Dictionary.ContainsKey(path))
MoveOne(path);
m_Dictionary.Add(path, number);
}
public void MoveOne(string path)
{
int number = m_Dictionary[path];
m_Dictionary.Remove(path);
var moved_node_path = IncrementPath(path);
if (m_Dictionary.ContainsKey(moved_node_path))
MoveOne(moved_node_path);
m_Dictionary.Add(moved_node_path, number);
}
private string IncrementPath(string path)
{
NodePath node_path = new NodePath(path);
node_path.Last().Index++;
return node_path.ConvertToStringFormat();
}
}
Когда потребитель пытается добавить путь, он проверяет, если она существует, если это произойдет, он перемещает существующие (приращения индекс последней части пути). Он делает это рекурсивно, если словарь также содержит элемент, в который мы пытаемся перейти.
Я испытал это так:
PathClass path_class = new PathClass();
path_class.Add("/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[1]/FormA1[1]" , 1);
path_class.Add("/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[1]/FormA1[1]", 2);
path_class.Add("/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[2]/FormA1[1]", 3);
path_class.Add("/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[2]/FormA1[2]", 4);
path_class.Add("/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[2]/FormA1[1]", 5);
я получил следующие результаты:
/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[1]/FormA1[2], 1
/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[1]/FormA1[1], 2
/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[2]/FormA1[2], 3
/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[2]/FormA1[3], 4
/ReturnState[1]/ReturnDataState[1]/Form6[1]/Body[1]/Member[2]/FormA1[1], 5
Пожалуйста, обратите внимание, что другой способ сделать это состоит в использовании Dictionary<NodePath,int>
, это означает, что вам нужно будет для осуществления Equals
и GetHashCode
для NodePath
.
UPDATE:
Если вы не заботитесь о модели, вы можете заменить IncrementPath
метод с этим (и удалить модель) для повышения производительности:
private string IncrementPath(string path)
{
int location_of_bracket_start = path.LastIndexOf("[");
if (location_of_bracket_start == -1)
throw new Exception("Unexpected format");
string before_bracket = path.Substring(0, location_of_bracket_start);
string rest = path.Substring(location_of_bracket_start);
int index = int.Parse(rest.Substring(1, rest.Length - 2));
index ++;
return string.Format("{0}[{1}]", before_bracket, index);
}
Является ли Ваш словарь 'Словарь'? В вашем примере ключ представляет собой целую строку '/ ReturnState [1]/ReturnDataState [1]/Form6 [1]/Body [1]/Member [1]/FormA1 [1]', а значение равно '94'? –
Да, ты прав Якуб! Я отредактирую свой вопрос, чтобы добавить больше ясности. – user3375390
Как насчет того, чтобы показать нам «простой метод CreatePathCollection (string path, int entityKey)» –