3

So i have the following JSON object:

var myObj = {
   Name: "Paul",
   Address: "27 Light Avenue"
}

and I want to convert its keys to lowercase such that i would get:

var newObj = {
   name: "Paul",
   address: "27 Light Avenue"
}

I tried the following:

var newObj = mapLower(myObj, function(field) {
    return field.toLowerCase();
})

function mapLower(obj, mapFunc) {
    return Object.keys(obj).reduce(function(result,key) {
         result[key] = mapFunc(obj[key])
         return result;
    }, {})
}

But I'm getting an error saying "Uncaught TypeError: field.toLowerCase is not a function".

Maxxx
  • 3,688
  • 6
  • 28
  • 55
  • There is a library called `humps` (https://github.com/domchristie/humps) which will handle several key transformations if you're trying to get to and from camelCase or PascalCase. If you know your keys are always 1 word, then you probably don't need it but if you had keys like "first_name" or "FirstName" or "firstName", `humps` can normalize all those to the same shape. – mr rogers Nov 17 '20 at 03:58

5 Answers5

6

I'm really not sure what you were trying to do there with your mapLower function but you only appear to be passing in one argument which is the object value.

Try something like this (not recursive)

var myObj = {
   Name: "Paul",
   Address: "27 Light Avenue"
}

const t1 = performance.now()

const newObj = Object.fromEntries(Object.entries(myObj).map(([ key, val ]) =>
  [ key.toLowerCase(), val ]))

const t2 = performance.now()

console.info(newObj)
console.log(`Operation took ${t2 - t1}ms`)

This takes all the object entries (an array of key / value pairs) and maps them to a new array with the keys lowercased before creating a new object from those mapped entries.


If you need this to handle nested objects, you'll want to use a recursive version

var myObj = {
  Name: "Paul",
  Address: {
    Street: "27 Light Avenue"
  }
}

// Helper function for detection objects
const isObject = obj => 
  Object.prototype.toString.call(obj) === "[object Object]"

// The entry point for recursion, iterates and maps object properties
const lowerCaseObjectKeys = obj =>
  Object.fromEntries(Object.entries(obj).map(objectKeyMapper))
  
// Converts keys to lowercase, detects object values
// and sends them off for further conversion
const objectKeyMapper = ([ key, val ]) =>
  ([
    key.toLowerCase(), 
    isObject(val)
      ? lowerCaseObjectKeys(val)
      : val
  ])

const t1 = performance.now()

const newObj = lowerCaseObjectKeys(myObj)

const t2 = performance.now()

console.info(newObj)
console.log(`Operation took ${t2 - t1}ms`)
Phil
  • 157,677
  • 23
  • 242
  • 245
2

This will solve your problem :

var myObj = {
   Name: "Paul",
   Address: "27 Light Avenue"
}

let result = Object.keys(myObj).reduce((prev, current) => 
({ ...prev, [current.toLowerCase()]: myObj[current]}), {})

console.log(result)
danh
  • 62,181
  • 10
  • 95
  • 136
tsamridh86
  • 1,480
  • 11
  • 23
  • 1
    This answer is the worst, its complexity make it unusable with big objects. My benchmarks with 1000 properties: laguf1.mobi's operation took 35 ms, Ami Hollander's operation took 44 ms, Phil's operation took 131 ms, @tsamridh86's operation took 11838 ms – Damien Garrido Jan 11 '22 at 10:17
1

var myObj = {
   Name: "Paul",
   Address: "27 Light Avenue"
}

Object.keys(myObj).map(key => {
  if(key.toLowerCase() != key){
    myObj[key.toLowerCase()] = myObj[key];
    delete myObj[key];
  }
});

console.log(myObj);
laguf1.mobi
  • 171
  • 6
0

I can't reproduce your error, but if you want to lower the key than you should do:

var myObj = {
  Name: "Paul",
  Address: "27 Light Avenue"
}

function mapLower(obj, mapFunc) {
  return Object.keys(obj).reduce(function(result, key) {
    result[mapFunc(key)] = obj[key]
    return result;
  }, {})
}

var newObj = mapLower(myObj, function(field) {
  return field.toLowerCase();
})

console.log(newObj)

will result with { name: 'Paul', address: '27 Light Avenue' }

Phil
  • 157,677
  • 23
  • 242
  • 245
Ami Hollander
  • 2,435
  • 3
  • 29
  • 47
0

Use json-case-convertor

const jcc = require('json-case-convertor')
var myObj = {
   Name: "Paul",
   Address: "27 Light Avenue"
}
const lowerCase = jcc.lowerCaseKeys(myObj)

Link to package: https://www.npmjs.com/package/json-case-convertor

SWIK
  • 714
  • 7
  • 12