2015-12-22 3 views
4

я получил строку как, A:<<Default>>;B:<<Default>>;C:<<Default>>;D:<<Default>>;E:<<Default>> [шаблон строка]Строка манипуляции с #

Представление строки, как ключ словаря: значение, которое группируется в виде строки с запятой в качестве разделителя.

Теперь после применения логики, я получаю список строк ниже,

A:aaa;E:eee 
D:ddd 
B:bbb;E:eee 

Теперь мне нужно сделать, приведенный выше список как один ниже (где ключ с новым значением должны быть размещены в правильном порядке и имеющий оставшиеся ключи со значениями по умолчанию),

A:aaa;B:<<Default>>;C:<<Default>>;D:<<Default>>;E:eee 
A:<<Default>>;B:<<Default>>;C:<<Default>>;D:ddd;E:<<Default>> 
A:<<Default>>;B:bbb;C:<<Default>>;D:<<Default>>;E:eee 

Пробная функция разделения, Замените и преобразуйте в список для достижения этой цели. Есть ли у нас эффективный способ добиться того же?

string constants = "A:<<Default>>;B:<<Default>>;C:<<Default>>;D:<<Default>>;E:<<Default>>"; 
      string placeHolder = string.Empty; 


      List<string> filteredkeys = new List<string>(); 
      List<string> formattedKeys = new List<string>(); 
      filteredkeys.Add("A:aaa;E:eee;"); 
      filteredkeys.Add("D:ddd;"); 
      filteredkeys.Add("B:bbb;E:eee;"); 

      foreach (var item in filteredkeys) 
      { 
       placeHolder = constants; 
       List<string> keyCombination = item.TrimEnd(';').Split(';').ToList(); 
       foreach (string keys in keyCombination) 
       { 
        List<string> abc = keys.Split(':').ToList(); 
        switch (abc[0]) 
        { 
         case "A": 
          placeHolder = placeHolder.Replace("A:<<Default>>", keys); 
          break; 
         case "B": 
          placeHolder = placeHolder.Replace("B:<<Default>>", keys); 
          break; 
         case "C": 
          placeHolder = placeHolder.Replace("C:<<Default>>", keys); 
          break; 
         case "D": 
          placeHolder = placeHolder.Replace("D:<<Default>>", keys); 
          break; 
         case "E": 
          placeHolder = placeHolder.Replace("D:<<Default>>", keys); 
          break; 
        }      
       } 
       formattedKeys.Add(placeHolder); 
      } 
+0

Что .NET вы используете (3,5, 4, 4,5 ...)? – Dialecticus

+0

Что случилось с Split? – slawekwin

+0

@fubo обновлен с куском кода, проверенным с помощью foreach & Switch case. Спасибо, что посмотрели на это :) – Programming

ответ

4

Linq решения:

String source = @"A:<<Default>>;B:<<Default>>;C:<<Default>>;D:<<Default>>;E:<<Default>>"; 

    // Note, that "E" value (eee:fff:ggg:hhh) contains semicolons 
    String values = "A:aaa;E:eee:fff:ggg:hhh"; 

    var dict = values 
    .Split(';') 
    .Select(item => item.Split(new Char[] {':'}, 2)) // "2": if value contains ':' 
    .ToDictionary(chunk => chunk[0], chunk => chunk[1]); 

    String result = String.Join(";", source 
    .Split(';') 
    .Select(item => item.Split(':')) 
    .Select(item => String.Join(":", 
     item[0], 
     dict.ContainsKey(item[0]) ? dict[item[0]] : item[1]))); 

    // Test 
    // A:aaa;B:<<Default>>;C:<<Default>>;D:<<Default>>;E:eee:fff:ggg:hhh 
    Console.Write(result); 
+0

не упоминается об этом, строка значений может содержать символ «:», когда значением является значение DataTime, например. Во всяком случае, большое спасибо, чтобы сделать мой код более простым в использовании выше linq. Попробуй с этим. – Programming

+0

@Programming: небольшая модификация (см. Мое редактирование) решит задачу: 'new Char [] {':'}, 2)' при создании словаря –

1

Это очень прямолинейное решение, которое просто анализирует строку, а затем применяет элементы к словарю вы проходите. Для того, чтобы использовать строку шаблона, вы просто применить шаблон строку первого, а затем применить фактическую строку, которую вы хотите обработать перезапись значения все по умолчанию, если соответствующие:

public void ParseAndApply(Dictionary<string, string> dictionary, string text) 
{ 
    foreach (string element in text.Split(';')) 
    { 
     string[] parts = element.Split(new char[]{ ':' }, 2); 
     dictionary[parts[0]] = parts[1]; 
    } 
} 

public string ConvertToString(Dictionary<string, string> dictionary) 
{ 
    return string.Join(";", dictionary.Select(kv => kv.Key + ":" + kv.Value)); 
} 

Используется так:

string[] strings = { "A:aaa;E:eee", "D:ddd", "B:bbb;E:eee" }; 

foreach (string exampleString in strings) 
{ 
    // create dictionary 
    Dictionary<string, string> dict = new Dictionary<string, string>(); 

    // apply from template string 
    string templateString = "A:<<Default>>;B:<<Default>>;C:<<Default>>;D:<<Default>>;E:<<Default>>"; 
    ParseAndApply(dict, templateString); 

    // apply example string 
    ParseAndApply(dict, exampleString); 

    // write output 
    Console.WriteLine(ConvertToString(dict)); 
} 
A:aaa;B:<<Default>>;C:<<Default>>;D:<<Default>>;E:eee 
A:<<Default>>;B:<<Default>>;C:<<Default>>;D:ddd;E:<<Default>> 
A:<<Default>>;B:bbb;C:<<Default>>;D:<<Default>>;E:eee 

Mis СЕПГ упомянуть об этом, значение строки может содержать символ «:», когда значение DataTime значение, например

Это не было бы проблемой, с этим решением, пока ключ не содержит двоеточие , Как мы разделили элемент на ParseAndApply, мы выполняем только разбить один раз на самый первый двоеточие в нем, поэтому дополнительные двоеточия, появляющиеся позже в значении, не являются проблемой.

0

Здесь с тестом прохождения блока,

[TestMethod] 
public void Test() 
{ 
    var template = "A:<<Default>>;B:<<Default>>;C:<<Default>>;D:<<Default>>;E:<<Default>>"; 

    Assert.AreEqual(Pair.Process("A:aaa;E:eee", template), 
     "A:aaa;B:<<Default>>;C:<<Default>>;D:<<Default>>;E:eee"); 

    Assert.AreEqual(Pair.Process("D:ddd", template), 
     "A:<<Default>>;B:<<Default>>;C:<<Default>>;D:ddd;E:<<Default>>"); 

    Assert.AreEqual(Pair.Process("B:bbb;E:eee", template), 
     "A:<<Default>>;B:bbb;C:<<Default>>;D:<<Default>>;E:eee"); 

} 

public class Pair 
{ 
    public static char InnerSeperator = ':'; 
    public static char OuterSeperator = ';'; 
    public static string DefaultValue = "<<Default>>"; 

    public Pair(string asString) 
    { 
     var strings = asString.Split(InnerSeperator).ToList(); 
     Key = strings[0]; 
     Value = strings.Count > 1 ? strings[1] : DefaultValue; 
    } 

    public string Key { get; set; } 
    public string Value { get; set; } 
    public override string ToString() 
    { 
     return string.Format("{0}{1}{2}", Key, InnerSeperator, Value); 
    } 

    public static string ToStringJoined(IEnumerable<Pair> pairs) 
    { 
     return string.Join(OuterSeperator.ToString(), pairs.Select(i => i.ToString())); 
    } 

    public static IEnumerable<Pair> FromJoinedString(string joined) 
    { 
     return joined.Split(OuterSeperator) 
      .Select(x => x.Trim()) 
      .Where(x => !string.IsNullOrWhiteSpace(x)) 
      .Select(x => new Pair(x)); 
    } 

    public static string Process(string values, string template) 
    { 
     var templateItems = FromJoinedString(template); 
     var valueItems = FromJoinedString(values); 
     var resultItems = templateItems.Select(t => valueItems.FirstOrDefault(x => x.Key == t.Key) ?? t); 
     return ToStringJoined(resultItems); 
    } 
} 

ура жизни ..