У меня есть список объектов JSON, каждый из которых я повторяю, и я просто хочу обработать в нем все KeyValuePairs, чтобы ключи были в верхнем регистре, а затем вернуть исправленные объекты.

Вот что я пытался:

 public static List<JObject> normalizeKeys(List<JObject> jObjList)
    {
        jObjList.ForEach(jobj => {
            foreach(var kvp in jobj)
            {
                kvp.Key = kvp.Key.ToUpper();
            }
        });

        return jObjList;

    }

Но он не выполняется, и вместо этого я получаю KeyValuePair<string, JToken>.Key cannot be assigned to -- it is readonly.. Есть ли у кого-нибудь предложения, как выполнить то, что мне нужно?

0
spb 18 Фев 2016 в 03:57

2 ответа

Лучший ответ

Хотя данный ответ работает, я был бы склонен сказать, что он не так элегантен, как мог бы быть, и не так полезен, как мог бы быть. Мы можем сделать больше и того, и другого. Для начала решим проблему для одного объекта:

public static JObject NormalizeKeys(JObject originalObject)
{
    var newObject = new JObject();
    foreach (var kvp in originalObject)
        newObject.Add(kvp.Key.ToUpper(), kvp.Value);
    return newObject;
}

А теперь решим задачу для списка:

var newList = oldList.Select(x=>NormalizeKeys(x)).ToList();

Или даже короче:

var newList = oldList.Select(NormalizeKeys).ToList();

Разве это не намного приятнее, чем все эти вложенные циклы? Скажите, как нормализовать один объект, а затем скажите, что вы хотите применить эту функцию к списку, и все готово.

9
Eric Lippert 18 Фев 2016 в 03:18

Думаю, вы сами знаете ответ, вы должны создать новую коллекцию и скопировать элементы, поскольку ключ является ключевым, он чувствителен к регистру и не может быть изменен, так как в противном случае вы можете получить, вероятно, 2 набора данных, один набор с обычным случай, а другой - в верхнем регистре.

Решение следующее:

public static List<JObject> normalizeKeys(List<JObject> jObjList)
{
    // create a new list for return and copy over the existing items
    var jObjReturnList = new List<JObject>(jObjList.Count);
    jObjList.ForEach(jobj =>
    {
        var jObjNew = new JObject();
        foreach (var kvp in jobj)
        {
            jObjNew.Add(kvp.Key.ToUpper(), kvp.Value);
        }

        jObjReturnList.Add(jObjNew);
    });

    return jObjReturnList;
}
2
Lin Song Yang 18 Фев 2016 в 01:11