如何最有效地将对象的所有键转换为小写?

101

我想出了一个

function keysToLowerCase (obj) {
  var keys = Object.keys(obj);
  var n = keys.length;
  while (n--) {
    var key = keys[n]; // "cache" it, for less lookups to the array
    if (key !== key.toLowerCase()) { // might already be in its lower case version
        obj[key.toLowerCase()] = obj[key] // swap the value to a new lower case key
        delete obj[key] // delete the old key
    }
  }
  return (obj);
}

不过我不确定 v8 的行为,例如它是否会真正删除其他键,还是只会删除引用,导致垃圾收集器最终会给我带来麻烦?

另外,我创建了这些测试,希望您能在那里添加您的答案,以便我们可以看到它们的匹配情况。

编辑1: 根据测试结果,如果不检查键名是否已经转换成小写,速度会更快,但除了速度更快之外,忽略这一步骤并创建新的小写键名是否会导致更多混乱?垃圾回收器是否会满意?


2
你能否创建一个新对象而不是修改现有的对象?这样你就可以跳过所有的删除操作。 - Jason Orendorff
@JasonOrendorff 显然它更慢,每次都会创建一个不必要的对象,垃圾收集器对此也不会满意... - João Pinto Jerónimo
很不幸,你的测试是错误的。SETUP部分仅在每个时钟循环中运行一次。由于你在设置中声明了对象,因此只有第一个测试的第一次迭代实际上将对象键更改为小写字母,所有其他迭代都会得到一个键已经为小写字母的对象。在[10]版本中修复(http://jsperf.com/object-keys-to-lower-case/10)。(大约一小时前我发表了类似的评论,我说它只运行一次。我注意到那是错误的,所以我删除了我的评论并进行了更多测试) - some
@一些人 我认为JasonOrendorff在第7版中进行了更正,我添加了一个不缓存键名的函数,一切都非常接近(对我来说,[1014、1080、1008]):http://jsperf.com/object-keys-to-lower-case/11 - João Pinto Jerónimo
@JoãoPintoJerónimo key.toLowerCase() 被调用了两次,你可以将其存储在一个变量中,并在下一行中使用它。而且创建一个新对象,只是添加新键比:添加新键到原始对象+删除先前的键更慢,这很奇怪? - S.Serpooshan
显示剩余4条评论
24个回答

0

const objectToLowercase = (data) => {
      const values = Object.values(data);
      if (values.length === 0) {
        return data;
      }

      return Object.keys(data).reduce((toLowerKeyObj, key) => {
        const isObject = typeof data[key] === 'object';
        const isArray = Array.isArray(data[key]);
        let value = null;

        if (isObject) {
          if (!isArray) {
            value = objectToLowercase(data[key]);
          }
        }

        if (isArray) {
          value = data[key].map(_value => {
            return objectToLowercase(_value);
          });
        }

        toLowerKeyObj[key.toLowerCase()] = isObject ? value : data[key];
        return toLowerKeyObj;
      }, {});
    };


0

大多数上面的答案都没有处理nullundefined值。为了解决这个问题,为什么不使用Lodash中的transform辅助函数呢?

const query = {
  Company: 'GH Works',
  Items: {
    Construction: 'FB',
    LineItems: {
      Quantity: '100',
      QUALity: 'checked'
    }
  }
}


function deepLowercaseKeys(hash) {
  return _.transform(hash, function(result, value, key) {
    const valueIsObject = typeof value === 'object';
    result[key.toLowerCase()] = valueIsObject ? deepLowercaseKeys(value) : value;
  });
}

console.log(deepLowercaseKeys(query))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

此外,您可以自定义该函数,然后使用它以任何您喜欢的方式转换对象。

const query = {
  Company: 'GH Works',
  Items: {
    Construction: 'FB',
    LineItems: {
      Quantity: '100',
      QUALity: 'checked'
    }
  }
}

// Base function
function deepTransform(hash, callback) {
  return _.transform(hash, function(result, value, key) {
    if (typeof value === 'object') {
      return callback(result, deepTransform(value, callback), key)
    }
    
    callback(result, value, key)
  })
}

// Custom function (can be anything)
function appendHello(hash) {
  return deepTransform(hash, function(result, value, key) {
    result[`${key}_hello`.toLowerCase()] = value;
  })
}

console.log(appendHello(query))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>


0
var aa = {ID:1,NAME:'Guvaliour'};
var bb= {};
var cc = Object.keys(aa);
cc.forEach(element=>{
 bb[element.toLowerCase()]=aa[element];
});
cosole.log(bb)

0
以下代码将所有键转换为小写:
array.forEach(item=>{
         
          let data = Object.keys(item).reduce((result, p) => (result[p.toLowerCase().trim()] = item[p], result), {})
          
          if(data.hasOwnProperty(fieldname)){
              if(data[fieldname]){
                if(!response['data'].includes(data[fieldname].toLowerCase()))
                    response['data'].push(data[fieldname]) 
                
             }
           }
          
        })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接