我想出了
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会如何表现,例如,它是否真的会删除其他键,还是只会删除引用,垃圾收集器会在以后咬我?
另外,我创建了these tests,我希望你能在那里添加你的答案,这样我们就能看出它们是如何匹配的。
编辑1: 显然,根据测试,如果我们不检查密钥是否已经是小写,但是速度更快,它会更快,是否会因为忽略这一点并创建新的小写密钥而造成更多的混乱?垃圾收集者会对此感到满意吗?
答案 0 :(得分:50)
我提出的fastest是你创建一个新对象:
var key, keys = Object.keys(obj);
var n = keys.length;
var newobj={}
while (n--) {
key = keys[n];
newobj[key.toLowerCase()] = obj[key];
}
我对v8目前的内部工作不够熟悉,无法给出明确的答案。几年前,我看到了开发人员谈论对象的视频和IIRC 它只会删除引用并让垃圾收集器处理它。但它是几年前所以即使它就像那样,它现在也不需要那样。
以后会咬你吗?这取决于你在做什么,但可能不是。创建短期对象非常常见,因此代码已经过优化以处理它。但每个环境都有其局限性,也许它会咬你。您必须使用实际数据进行测试。
答案 1 :(得分:28)
我这样使用Lo-Dash.transform:
var lowerObj = _.transform(obj, function (result, val, key) {
result[key.toLowerCase()] = val;
});
答案 2 :(得分:20)
我个人使用:
let objectKeysToLowerCase = function (origObj) {
return Object.keys(origObj).reduce(function (newObj, key) {
let val = origObj[key];
let newVal = (typeof val === 'object') ? objectKeysToLowerCase(val) : val;
newObj[key.toLowerCase()] = newVal;
return newObj;
}, {});
}
它简洁,重复处理嵌套对象并返回一个新对象而不是修改原始对象。
在我有限的本地测试中,此功能比目前列出的其他递归解决方案(一旦修复)更快。我喜欢将它与其他人进行对比,但jsperf此刻正在下降(???)。
它也是用ES5.1编写的,所以根据MDN的文档,它应该适用于FF 4 +,Chrome 5 +,IE 9.0 +,Opera 12 +,Safari 5+(所以,几乎一切)。
Vanilla JS获胜。
我不会太担心这一切的垃圾收集方面。一旦对旧对象的所有引用都被销毁,它将是GC,但 new 对象仍将基本上引用它的所有属性,因此它们不会。
任何函数,数组或RegExp将被复制"参考文献。在内存方面,由于大多数(全部?)现代JS引擎用户string interning,因此即使字符串也不会被这个过程复制。我认为只剩下形成原始结构的数字,布尔和对象留下了GC' d。
请注意,如果原始文件具有多个具有相同小写字母的属性,则此过程的所有实现都将丢失值。即:
let myObj = { xx: 'There', xX: 'can be', Xx: 'only', XX: 'one!' };
console.log(myObj);
// { xx: 'There', xX: 'can be', Xx: 'only', XX: 'one!' }
let newObj = objectKeysToLowerCase(myObj);
console.log(newObj);
// { xx: 'one!' }
当然,有时这正是你想要的。
更新2018-07-17
有些人注意到原始功能对阵列效果不佳。这是一个扩展的,更具弹性的版本。它通过数组正确地重复,并且如果初始值是数组或简单值,则可以工作:
let objectKeysToLowerCase = function (input) {
if (typeof input !== 'object') return input;
if (Array.isArray(input)) return input.map(objectKeysToLowerCase);
return Object.keys(input).reduce(function (newObj, key) {
let val = input[key];
let newVal = (typeof val === 'object') ? objectKeysToLowerCase(val) : val;
newObj[key.toLowerCase()] = newVal;
return newObj;
}, {});
};
答案 3 :(得分:5)
loDash / fp方式,相当不错,因为它基本上是一个单线
#!/usr/bin/env python
# Vocabulary.py
# GUI program to manage unknown words
from tkinter import *
class Word:
def __init__(self, wordorphrase, explanation, translation, example):
self.wordorphrase = wordorphrase
self.explanation = explanation
self.translation = translation
self.example = example
class Vocabulary(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master = master
self.master.resizable(width = False, height = False)
self.master.title("Vocabulary")
self.create_widgets()
def create_widgets(self):
lblWordsOrPhrases = Label(self.master, text = 'Words or Phrases:')
lblWordsOrPhrases.grid(row = 0, column = 0)
lblWordOrPhrase = Label(self.master, text = 'Word or phrase:')
lblWordOrPhrase.grid(row = 0, column = 1, sticky = W)
listBox = Listbox(self.master,
height = 34,
width = 30)
listBox.grid(row = 1, column = 0, rowspan = 7)
txt_WordOrPhrase = Text(self.master,
height = 1,
width = 40)
txt_WordOrPhrase.grid(row = 1, column = 1, sticky = N)
lblExplanation = Label(self.master, text = 'Explanation:')
lblExplanation.grid(row = 2, column = 1, sticky = W)
txt_Explanation = Text(self.master,
height = 10,
width = 40)
txt_Explanation.grid(row = 3, column = 1, sticky = N)
lblTranslation = Label(self.master, text = 'Translation:')
lblTranslation.grid(row = 4, column = 1, sticky = W)
txt_Explanation = Text(self.master,
height = 10,
width = 40)
txt_Explanation.grid(row = 5, column = 1, sticky = N)
lblExamples = Label(self.master, text = 'Example(s):')
lblExamples.grid(row = 6, column = 1, sticky = W)
txt_Explanation = Text(self.master,
height = 10,
width = 40)
txt_Explanation.grid(row = 7, column = 1, sticky = S)
btn_Add = Button(self.master,
text = 'Add',
command = self.add_item)
btn_Add.grid(row = 8, column = 0, sticky = W)
def get_word(self):
return self.txt_WordOrPhrase.get('1.0', '1.0 lineend')
def get_explanation(self):
return self.txt_Explanation.get('1.0', '1.0 lineend')
def get_translation(self):
return self.txt_Translation.get('1.0', '1.0 lineend')
def get_example(self):
return self.txt_Example.get('1.0', '1.0 lineend')
def add_item(self):
self.listBox.insert(END, self.get_word())
def main():
root = Tk()
Vocabulary(root)
root.mainloop()
if __name__ == '__main__':
main()
答案 4 :(得分:3)
在我的测试中使用forEach似乎更快一些 - 并且原始引用已经消失,因此删除新引用将使其达到g.c的范围。
function keysToLowerCase(obj){
Object.keys(obj).forEach(function (key) {
var k = key.toLowerCase();
if (k !== key) {
obj[k] = obj[key];
delete obj[key];
}
});
return (obj);
}
var O = {ONE:1,2:2,tHree:3,FOUR:4,Five:5,SIX:{a:1,b:2,c:3,D:4,E :5}}; keysToLowerCase(O); 强>
/ *返回值:(对象)* /
{
five:5,
four:4,
one:1,
six:{
a:1,
b:2,
c:3,
D:4,
E:5
},
three:3,
two:2
}
答案 5 :(得分:3)
这是将所有json键转换为小写字母的最简单解决方案。
let o = {"Account_Number ":"0102301", "customer_NaME":"name"}
o = Object.keys(o).reduce((c, k) => (c[k.toLowerCase().trim()] = o[k], c), {})
console.log(o)
答案 6 :(得分:3)
Object.fromEntries
(ES.next)使用新的Object.fromEntries
方法的原生且不变的解决方案:
const newObj = Object.fromEntries(
Object.entries(obj).map(([k, v]) => [k.toLowerCase(), v])
);
直到该功能广泛可用,您可以使用以下ES.next polyfill自己定义它:
Object.fromEntries = arr => Object.assign({}, ...Array.from(arr, ([k, v]) => ({[k]: v}) ));
一件好事是,此方法的作用与Object.entries
相反,因此现在您可以在对象和数组表示形式之间来回移动。
答案 7 :(得分:2)
ES6版本:
Object.keys(source)
.reduce((destination, key) => {
destination[key.toLowerCase()] = source[key];
return destination;
}, {});
答案 8 :(得分:1)
我以类似的方式回答了问题,但是我使用ES6和TypeScript。 toLowerCaseObject函数将Array作为参数,并递归地遍历JSON树并使每个节点都变为小写:
function toLowerCaseObject(items: any[]) {
return items.map(x => {
let lowerCased = {}
for (let i in x) {
if (x.hasOwnProperty(i)) {
lowerCased[i.toLowerCase()] = x[i] instanceof Array ? toLowerCaseObject(x[i]) : x[i];
}
}
return lowerCased;
});
}
答案 9 :(得分:1)
DECLARE @cmdINSERT varchar(8000);
declare @dowhere binary;
declare @date varchar(10);
set @dowhere = 1;
set @date = '14.03.2020';
set @cmdINSERT =
'SELECT *
FROM [TABLE]
WHERE [Changed At] >=
CASE WHEN ' + @dowhere + '
when 1 THEN ''' + @date + '''
ELSE [Changed At]
end;'
EXEC(@cmdINSERT)
适用于嵌套对象。
答案 10 :(得分:0)
考虑将案例降低一次,将其存储在lowKey
var:
function keysToLowerCase (obj) {
var keys = Object.keys(obj);
var n = keys.length;
var lowKey;
while (n--) {
var key = keys[n];
if (key === (lowKey = key.toLowerCase()))
continue
obj[lowKey] = obj[key]
delete obj[key]
}
return (obj);
}
答案 11 :(得分:0)
对于简单的情况,您可以使用以下示例将所有键转换为小写:
Object.keys(example).forEach(key => {
const value = example[key];
delete example[key];
example[key.toLowerCase()] = value;
});
您可以使用toUpperCase()
而不是toLowerCase()
将所有键转换为大写:
Object.keys(example).forEach(key => {
const value = example[key];
delete example[key];
example[key.toUpperCase()] = value;
});
答案 12 :(得分:0)
对于所有值:
to_lower_case = function(obj) {
for (var k in obj){
if (typeof obj[k] == "object" && obj[k] !== null)
to_lower_case(obj[k]);
else if(typeof obj[k] == "string") {
obj[k] = obj[k].toLowerCase();
}
}
return obj;
}
相同的键可以进行细微的调整。
答案 13 :(得分:0)
这就是我的方法。我的输入可以是任何东西,并且可以通过嵌套对象和对象数组重复使用。
const fixKeys = input => Array.isArray(input)
? input.map(fixKeys)
: typeof input === 'object'
? Object.keys(input).reduce((acc, elem) => {
acc[elem.toLowerCase()] = fixKeys(input[elem])
return acc
}, {})
: input
使用摩卡测试
const { expect } = require('chai')
const fixKeys = require('../../../src/utils/fixKeys')
describe('utils/fixKeys', () => {
const original = {
Some: 'data',
With: {
Nested: 'data'
},
And: [
'an',
'array',
'of',
'strings'
],
AsWellAs: [
{ An: 'array of objects' }
]
}
const expected = {
some: 'data',
with: {
nested: 'data'
},
and: [
'an',
'array',
'of',
'strings'
],
aswellas: [{ an: 'array of objects' }]
}
let result
before(() => {
result = fixKeys(original)
})
it('left the original untouched', () => {
expect(original).not.to.deep.equal(expected)
})
it('fixed the keys', () => {
expect(result).to.deep.equal(expected)
})
})
答案 14 :(得分: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)
答案 15 :(得分:0)
单线(仅适用于顶级按键):
Object.assign(...Object.keys(obj).map(key => ({[key.toLowerCase()]: obj[key]})))
转化:
{ a: 1, B: 2, C: { Z: 4 } }
收件人:
{ a: 1, b: 2, c: { Z: 4 } }
答案 16 :(得分:0)
这不是最干净的方法,但它已为我的团队使用,因此值得分享。
我创建此方法是因为后端运行的语言不区分大小写,并且数据库和后端将产生不同的关键案例。对于我们来说,它完美地工作了。请注意,我们将日期作为字符串发送,而我们不发送函数。
我们已将其简化为这一行。
const toLowerCase = (data) => JSON.parse(JSON.stringify(data).replace(/"([^"]+)":/g, ($0, key) => '"' + key.toString().toLowerCase() + '":'))
我们使用JSON.parse(JSON.stringify(obj))
方法克隆对象。这将以JSON格式生成对象的字符串版本。当对象为字符串形式时,您可以使用正则表达式,因为JSON是可转换所有密钥的可预测格式。
分解成这样。
const toLowerCase = function (data) {
return JSON.parse(JSON.stringify(data)
.replace(/"([^"]+)":/g, ($0, key) => {
return '"' + key.toString().toLowerCase() + '":'
}))
}
答案 17 :(得分: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])
}
}
})
答案 18 :(得分:0)
这是基于上述示例之一的递归版本。
//updated function
var lowerObjKeys = function(obj) {
Object.keys(obj).forEach(function(key) {
var k = key.toLowerCase();
if (k != key) {
var v = obj[key]
obj[k] = v;
delete obj[key];
if (typeof v == 'object') {
lowerObjKeys(v);
}
}
});
return obj;
}
//plumbing
console = {
_createConsole: function() {
var pre = document.createElement('pre');
pre.setAttribute('id', 'console');
document.body.insertBefore(pre, document.body.firstChild);
return pre;
},
info: function(message) {
var pre = document.getElementById("console") || console._createConsole();
pre.textContent += ['>', message, '\n'].join(' ');
}
};
//test case
console.info(JSON.stringify(lowerObjKeys({
"StackOverflow": "blah",
"Test": {
"LULZ": "MEH"
}
}), true));
请注意,它不会跟踪循环引用,因此最终会出现无限循环,从而导致堆栈溢出。
答案 19 :(得分:0)
使用TypeScript
/**
* Lowercase the keys of an object
* @example
lowercaseKeys({FOO: true, bAr: false}); // {foo: true, bar: false}
*/
export function lowercaseKeys<T>(object: { [key: string]: T }): { [key: string]: T } {
const result: { [key: string]: T } = {};
for (const [key, value] of Object.entries(object)) {
result[key.toLowerCase()] = value;
}
return result;
}
用法
lowercaseKeys({FOO: true, bAr: false}); // {foo: true, bar: false}