代码之家  ›  专栏  ›  技术社区  ›  Armstrongest

最有效的带格式的字典。

  •  10
  • Armstrongest  · 技术社区  · 14 年前

    将字典转换为格式化字符串的最有效方法是什么?

    例如。:

    我的方法是:

    public string DictToString(Dictionary<string, string> items, string format){
    
        format = String.IsNullOrEmpty(format) ? "{0}='{1}' " : format;
    
        string itemString = "";
        foreach(var item in items){
            itemString = itemString + String.Format(format,item.Key,item.Value);
        }
    
        return itemString;
    }
    

    有没有更好/更简洁/更有效的方法?

    注意:字典最多有10个项,如果存在其他类似的“键值对”对象类型,我不会使用它。

    另外,由于我无论如何都要返回字符串,一般版本会是什么样子?

    7 回复  |  直到 7 年前
        1
  •  22
  •   Gabe Timothy Khouri    14 年前

    我只是重写了你的版本,让它更通用一些 StringBuilder :

    public string DictToString<T, V>(IEnumerable<KeyValuePair<T, V>> items, string format)
    {
        format = String.IsNullOrEmpty(format) ? "{0}='{1}' " : format; 
    
        StringBuilder itemString = new StringBuilder();
        foreach(var item in items)
            itemString.AppendFormat(format, item.Key, item.Value);
    
        return itemString.ToString(); 
    }
    
        2
  •  16
  •   Lee    14 年前
    public string DictToString<TKey, TValue>(Dictionary<TKey, TValue> items, string format)
    {
        format = String.IsNullOrEmpty(format) ? "{0}='{1}' " : format;
        return items.Aggregate(new StringBuilder(), (sb, kvp) => sb.AppendFormat(format, kvp.Key, kvp.Value)).ToString();
    }
    
        3
  •  9
  •   abatishchev Marc Gravell    14 年前

    这种方法

    public static string ToFormattedString<TKey, TValue>(this IDictionary<TKey, TValue> dic, string format, string separator)
    {
        return String.Join(
            !String.IsNullOrEmpty(separator) ? separator : " ",
            dic.Select(p => String.Format(
                !String.IsNullOrEmpty(format) ? format : "{0}='{1}'",
                p.Key, p.Value)));
    }
    

    使用下一种方法:

    dic.ToFormattedString(null, null); // default format and separator
    

    将转换

    new Dictionary<string, string>
    {
        { "a", "1" },
        { "b", "2" }
    };
    

    a='1' b='2'
    

    dic.ToFormattedString("{0}={1}", ", ")
    

    a=1, b=2
    

    不要忘记超载:

    public static string ToFormattedString<TKey, TValue>(this IDictionary<TKey, TValue> dic)
    {
        return dic.ToFormattedString(null, null);
    }
    

    您可以使用通用 TKey / TValue 因为任何物体 ToString() 它将被 String.Format() .

    而且到目前为止 IDictionary<TKey, TValue> IEnumerable<KeyValuePair<TKey, TValue>> 你可以用任何。我更喜欢IDictionary以获得更多的代码表达能力。

        4
  •  3
  •   BorisSh    7 年前

    用linq和string.join()(c 6.0)在一行中格式化字典:

    Dictionary<string, string> dictionary = new Dictionary<string, string>()
    {
        ["key1"] = "value1",
        ["key2"] = "value2"             
    };
    
    string formatted = string.Join(", ", dictionary.Select(kv => $"{kv.Key}={kv.Value}")); // key1=value1, key2=value2
    

    您可以这样创建简单的扩展方法:

    public static class DictionaryExtensions
    {
        public static string ToFormatString<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, string format = null)
        {
            format = string.IsNullOrEmpty(format) ? "{0}='{1}'" : format;
            return string.Join(", ", dictionary.Select(kv => string.Format(format, kv.Key, kv.Value)));
        }
    }
    
        5
  •  2
  •   dpnmn    8 年前

    使用扩展方法和默认参数,并将键/值对包装在:

    public static string ItemsToString<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> items, string format = "{0}='{1}' ")
    {
        return items
            .Aggregate(new StringBuilder("{"), (sb, kvp) => sb.AppendFormat(format, kvp.Key, kvp.Value))
            .Append('}')
            .ToString();
    }
    

    然后可以直接从Dictionary/Enumerable调用该方法:

    string s = myDict.ItemsToString()
    
        6
  •  1
  •   Skurmedel    14 年前

    我认为只有10根弦就不需要考虑效率问题,但也许你不想仅仅依靠10根弦。

    字符串串联在内存中创建一个新的字符串对象,因为字符串对象是不可变的。这还建议其他字符串操作可以创建新实例,如replace。通常使用StringBuilder可以避免这种情况。

    StringBuilder通过使用它所操作的缓冲区来避免这种情况;当StringBuilder的值与另一个字符串连接时,内容将添加到缓冲区的末尾。

    但是有一些警告,请参见 this paragraph :

    性能注意事项

    […]

    串联的性能 字符串或的操作 StringBuilder对象取决于 通常会发生内存分配。一 字符串连接操作始终 分配内存,而 StringBuilder连接操作 仅当 StringBuilder对象缓冲区也是 小到可以容纳新数据。 因此,字符串类是 最好是串联 如果字符串的固定数目 对象被连接。在那 案例,个别串联 操作甚至可以组合成 由编译器执行的单个操作。一 StringBuilder对象更适合于 一个串联操作,如果 任意数量的字符串是 连接;例如,如果循环 连接随机数 用户输入字符串。

    因此,这样一个(人为的)案例可能不应该用StringBuilder替换:

    string addressLine0 = Person.Street.Name +  " " + Person.Street.Number + " Floor " + Person.Street.Floor;
    

    …因为编译器可能能够将其简化为更有效的形式。如果它的效率不足以在更大的事情计划中发挥重要作用,这也是一个极具争议的问题。

    按照Microsoft的建议,您可能希望改用StringBuilder(如其他充分的答案所示)。

        7
  •  0
  •   James Curran    14 年前

    加布,如果你想成为普通人,就要成为普通人:

    public string DictToString<T>(IDictionary<string, T> items, string format) 
    { 
        format = String.IsNullOrEmpty(format) ? "{0}='{1}' " : format;  
    
        StringBuilder itemString = new StringBuilder(); 
        foreach(var item in items) 
            itemString.AppendFormat(format, item.Key, item.Value); 
    
        return itemString.ToString();  
    }