16

我从服务器收到一个 json 响应,看起来像这样:

{
    "Response": {
        "FirstName": "John",
        "LastName": "Smith",
        "NickNames": {
            "NameOne": "Johnny",
            "NameTwo": "JohnS",
            "NameThree": "Smithy"
        },
        "Success": true,
        "Errors": []
    }
}

有没有办法可以通过一个函数运行这个响应,以便每个键值对的键都是驼峰式的?

所以输出看起来像:

{
    "response": {
        "firstName": "John",
        "lastName": "Smith",
        "nickNames": {
            "nameOne": "Johnny",
            "nameTwo": "JohnS",
            "nameThree": "Smithy"
        },
        "success": true,
        "errors": []
    }
}

如果有人能指出我正确的方向,那就太好了。

谢谢。

4

5 回答 5

25

您将提供JSON.parse一个 reviver 函数,该函数将值分配给小写的新属性。

function toCamelCase(key, value) {
  if (value && typeof value === 'object'){
    for (var k in value) {
      if (/^[A-Z]/.test(k) && Object.hasOwnProperty.call(value, k)) {
        value[k.charAt(0).toLowerCase() + k.substring(1)] = value[k];
        delete value[k];
      }
    }
  }
  return value;
}

var parsed = JSON.parse(myjson, toCamelCase);

有关它如何在这个 SO answer 中工作的更多信息。

于 2012-11-26T00:22:26.780 回答
10

用户“@I Hate Lazy”建议的方法——使用“reviver”功能是正确的。但是他的功能对我不起作用。

也许是因为我正在解析一个 JSON 数组。我还使用了Resharper,它抱怨代码有异味 :)(“并非所有代码路径都返回一个值”)。所以我最终使用了另一个对我有用的SO 问题中的函数:

function camelCaseReviver(key, value) {
    if (value && typeof value === 'object') {
        for (var k in value) {
            if (/^[A-Z]/.test(k) && Object.hasOwnProperty.call(value, k)) {
                value[k.charAt(0).toLowerCase() + k.substring(1)] = value[k];
                delete value[k];
            }
        }
    }
    return value;
}
于 2014-11-26T15:01:11.637 回答
5

这是一种功能递归(ES6)方法。

function convertKeysToCamelCase(o) {
  if (o === null || o === undefined) {
    return o;
  } else if (Array.isArray(o)) {
    return o.map(convertKeysToCamelCase);
  }
  return typeof o !== 'object' ? o : Object.keys(o).reduce((prev, current) => {
    const newKey = `${current[0].toLowerCase()}${current.slice(1)}`;
    if (typeof o[current] === 'object') {
      prev[newKey] = convertKeysToCamelCase(o[current]);
    } else {
      prev[newKey] = o[current];
    }
    return prev;
  }, {});
}

// successfully tested input
const o = {
  SomeNum: 1,
  SomeStr: 'a',
  SomeNull: null,
  SomeUndefined: undefined,
  SomeBoolean: true,
  SomeNaN: NaN,
  NestedObject: {
    SomeSentence: 'A is for apple',
    AnotherNested: {
      B: 'is for blahblah'
    }
  },
  NumArray: [1, 2, 3, 4],
  StringArray: ['a', 'b', 'c'],
  BooleanArray: [true, false],
  ArrayOfArrays: [[1,2,], ['a','b']],
  ObjectArray: [{Foo:'bar'}, {Hello:'world', Nested:{In:'deep'}}],
  MixedArray: [1,'a', true, null, undefined, NaN, [{Foo:'bar'}, 'wat']]
}

const output = convertKeysToCamelCase(o);

console.log(output.mixedArray[6][0].foo); // 'bar'
于 2016-07-15T18:41:12.913 回答
1

@adamjyee您的解决方案除了嵌套的整数数组外有效。一个小的修复可能是:

function convertKeysToCamelCase (o) {
    if (o === null) {
      return null
    } else if (o === undefined) {
      return undefined
    } else if (typeof o === 'number') {
      return o
    } else if (Array.isArray(o)) {
      return o.map(convertKeysToCamelCase)
    }
    return Object.keys(o).reduce((prev, current) => {
      const newKey = `${current[0].toLowerCase()}${current.slice(1)}`
      if (typeof o[current] === 'object') {
        prev[newKey] = convertKeysToCamelCase(o[current])
      } else {
        prev[newKey] = o[current]
      }
      return prev
    }, {})

[评论权但缺乏评论特权:(]

于 2017-05-12T00:50:32.660 回答
0

您需要编写一个递归函数来遍历树并返回一个新树,其中对象中的键已被更新。递归函数将调用自身来处理它遇到的任何子对象。

于 2012-11-26T00:20:25.313 回答