Чи є спосіб зручно перетворити словник на String?


77

Я виявив, що реалізація ToString за замовчуванням у словнику - це не те, що я хочу. Я хотів би мати {key=value, ***}.

Будь-який зручний спосіб отримати його?


3
Це для візуалізації лише у налагоджувачі? Або цей рядок призначений для користувача?
TreDubZedd

1
Я думаю, це дуже добре зроблено серіалізатором JSON
Shekhar_Pro

Відповіді:


115

Спробуйте цей метод розширення:

public static string ToDebugString<TKey, TValue> (this IDictionary<TKey, TValue> dictionary)
{
    return "{" + string.Join(",", dictionary.Select(kv => kv.Key + "=" + kv.Value).ToArray()) + "}";
}

1
Я не бачу потреби ні в тому ToArray(), ні в ToString()тому.
Стівен Джеуріс,

3
@StevenJeuris: ToArray()насправді потрібен, якщо ви використовуєте версію нижче NET 4.0
Джек

1
точно як map.toString () в java;)
Холецький

114

Якщо ви просто хочете провести серіалізацію для цілей налагодження, коротшим способом є використання String.Join:

var asString = string.Join(Environment.NewLine, dictionary);

Це працює, тому що IDictionary<TKey, TValue>знаряддя IEnumerable<KeyValuePair<TKey, TValue>>.

Приклад

Console.WriteLine(string.Join(Environment.NewLine, new Dictionary<string, string> {
    {"key1", "value1"},
    {"key2", "value2"},
    {"key3", "value3"},
}));
/*
[key1, value1]
[key2, value2]
[key3, value3]
*/

Чудово працює. Дуже дякую.
Marty_in_a_Box

6
Блискуче! Де це було все моє життя?
Тоні

3
Зауважте, що для цього потрібен .NET 4
cowlinator

2
Не працює з ListDictionary. Інакше чудово, голос за голос
Алекс

10

Як щодо методу розширення, такого як:

public static string MyToString<TKey,TValue>
      (this IDictionary<TKey,TValue> dictionary)
{
    if (dictionary == null)
        throw new ArgumentNullException("dictionary");

    var items = from kvp in dictionary
                select kvp.Key + "=" + kvp.Value;

    return "{" + string.Join(",", items) + "}";
}

Приклад:

var dict = new Dictionary<int, string>
{
    {4, "a"},
    {5, "b"}
};

Console.WriteLine(dict.MyToString());

Вихід:

{4=a,5=b}

Подих і вкажіть, що це метод розширення: D
Матіас Фідемайзер

8

Немає зручного способу. Доведеться катати свою.

public static string ToPrettyString<TKey, TValue>(this IDictionary<TKey, TValue> dict)
{
    var str = new StringBuilder();
    str.Append("{");
    foreach (var pair in dict)
    {
        str.Append(String.Format(" {0}={1} ", pair.Key, pair.Value));
    }
    str.Append("}");
    return str.ToString();
}

1
Це корисно, оскільки це працює на попередньому коді .NET3.5 (без підтримки linq)
Джон Сіблі

4

Може бути:

string.Join
(
    ",",
    someDictionary.Select(pair => string.Format("{0}={1}", pair.Key.ToString(), pair.Value.ToString())).ToArray()
);

Спочатку ви повторюєте кожну пару ключ-значення та форматуєте її так, як хотіли б бачити як рядок, а згодом перетворюєте в масив і об’єднуєте в єдиний рядок.


3

Я отримав цю просту відповідь .. Використовуйте JavaScriptSerializerдля цього клас.

І ви можете просто викликати метод Serialize з об'єктом Dictionary як аргументом.

Приклад:

var dct = new Dictionary<string,string>();
var js = new JavaScriptSerializer();
dct.Add("sam","shekhar");
dct.Add("sam1","shekhar");
dct.Add("sam3","shekhar");
dct.Add("sam4","shekhar");
Console.WriteLine(js.Serialize(dct));

Вихід:

{"sam":"shekhar","sam1":"shekhar","sam3":"shekhar","sam4":"shekhar"}

3

Якщо ви хочете використовувати Linq, ви можете спробувати щось подібне:

String.Format("{{{0}}}", String.Join(",", test.OrderBy(_kv => _kv.Key).Zip(test, (kv, sec) => String.Join("=", kv.Key, kv.Value))));

де "тест" - це ваш словник. Зверніть увагу, що перший параметр для Zip () - це просто заповнювач, оскільки нуль не може бути переданий).

Якщо формат не важливий, спробуйте

String.Join(",", test.OrderBy(kv => kv.Key));

Що дасть вам щось на зразок

[key,value], [key,value],...

Мені більше подобається вираз Linq @Tim.
seairth

1

Інше рішення:

var dic = new Dictionary<string, double>()
{
    {"A", 100.0 },
    {"B", 200.0 },
    {"C", 50.0 }
};

string text = dic.Select(kvp => kvp.ToString()).Aggregate((a, b) => a + ", " + b);

Значення тексту: [A, 100], [B, 200], [C, 50]


0

Ви можете прокрутити Ключі Словника та роздрукувати їх разом із значенням ...

public string DictToString(Dictionary<string, string> dict)
{
    string toString = "";
    foreach (string key in dict.Keys)
    {
            toString += key + "=" + dict[key];
    }
    return toString;
}

0

Мені подобається підхід ShekHar_Pro до використання серіалізатора. Єдина рекомендація - використовувати json.net для серіалізації, а не вбудований JavaScriptSerializer, оскільки це повільніше.


0

Мені дуже подобаються рішення з методом розширення вище, але їм не вистачає однієї дрібниці для майбутнього - вхідних параметрів для роздільників, отже:

    public static string ToPairString<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, string pairSeparator, string keyValueSeparator = "=")
    {
        return string.Join(pairSeparator, dictionary.Select(pair => pair.Key + keyValueSeparator + pair.Value));
    }

Приклад використання:

string result = myDictionary.ToPairString(Environment.NewLine, " with value: ");

-5

Що вам потрібно зробити, це створити клас, що розширює Dictionaryі перезаписуєToString() метод.

Побачимось


Чи можу я знати, чому хтось вказав -1 на це? :) дякую, якщо я помиляюся, я хотів би, де я помиляюся. Дякую.
Амедіо

3
Я не підтримав цю відповідь, але вона не містить зразка коду. Крім того, підкласифікація здається непотрібним молотком, коли ви можете просто написати метод розширення, як показано в деяких інших відповідях; це також дозволяє вам викликати метод розширення безпосередньо в словниках, які ви отримуєте з коду поза вашим контролем, де ви не зможете просто використовувати свій підклас.
Еліот
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.