繁体   English   中英

使用正则表达式重命名对象数组的键

[英]Use regex to rename keys of array of objects

我有一个对象数组。 每个对象都有很多键(超过 100 个),其中一些键可能有我想删除的特殊字符。

我尝试以这种方式做我想做的事:

const result = data.map(datum => {
  const keys = Object.keys(datum)
  const replacedKeys = keys.map(key => {
    const newKey = key.replace(/[.|&;$%@%"<>+]/g, '')
  })
  // ??
})

但我确定这不是正确的方法..

您可以使用新键映射新对象并​​使用Object.assign创建单个对象。

const result = data.map(datum => Object.assign(...Object
    .keys(datum)
    .map(key => ({ [key.replace(/[.|&;$%@%"<>+]/g, '')]: datum[key] }))
));

使用已经在 FireFox 中找到的 ES8 Object.fromEntries方法,您可以执行以下操作:

 const sanitiseKeys = o => Object.fromEntries(Object.entries(o).map(([k,v]) => [k.replace(/[.|&;$%@%"<>+]/g,""), v])); // Example use: var data = [{ "name#": "John" }, { "@key": 2 }]; data = data.map(sanitiseKeys); console.log(data);

如果还没有实现,这里是一个 polyfill:

Object.fromEntries = arr => Object.assign({}, ...arr.map( ([k, v]) => ({[k]: v}) ));

您可以使用JSON.stringify()将纯 JavaScript 对象转换为JSON并使用String.prototype.replace()匹配有效JSON的属性,然后使用JSON.parse()转换回纯 JavaScript 对象。

从字符类中删除了"因为有效的JSON属性被双引号"括起来。

RegExp

([.|&;$%@%<>+]+)(?=([^\1]+|)":)

创建一个包含字符类的捕获组,并匹配字符类后跟一个或多个不在字符类中的字符,后跟属性名称的双引号"后跟冒号字符或双引号后跟冒号字符。

匹配的字符类可以替换为空字符串''或任何其他字符。

 let o = {"aB|c&D;0$_%@q%<Z>5+":1}; console.log(o); o = JSON.parse(JSON.stringify(o).replace(/([.|&;$%@%<>+]+)(?=([^\\1]+|)":)/g, '')); console.log( JSON.stringify(o) , /[.|&;$%@%<>+]+/.test(Object.keys(o)[0]) // false );

该解决方案依赖于String.prototype.replace() ,因此它可以将String s 或RegExp s 作为源,并允许替换。 请记住,它的性能不是很好,但它仅使用纯函数:

 const data = { someKey: 1, some0Key: 1, some1Key: 1, some2Key: 1, some3Key: 1, some4Key: 1, some5Key: 1, some6Key: 1, some7Key: 1, some8Key: 1, some9Key: 1, some10Key: 1, some11Key: 1, some12Key: 1, some13Key: 1, some14Key: 1, some15Key: 1, }; // simple equivalent of proposed Object.fromEntries() const fromEntries = (entries) => entries.reduce((obj, [key, value]) => ({ [key]: value, ...obj }), {}); const replaceObjectKeys = (obj, from, to) => fromEntries( Object.entries(obj) .map(([key, value]) => [key.replace(from, to), value])); console.log(replaceObjectKeys(data, /Key$/, 'prop'));

fromEntries可以很容易地重写为更快的实现,代价是引入可变变量。

考虑使用Array#reduce()来聚合输入对象键的值。 这样做的原因是您的键清理(即从键中删除不需要的字符)可能会导致输入对象的不同键/值对“减少”,以便清理的键有效地与多个值相关。 例如一个输入对象,如:

const data = {
  'key' : 'value0',
  'key&&&' : 'value1',
  'key$%<>' : 'value2'
}

将(基于您的卫生)产生一个输出对象,其中包含与多个值相关的单个key

const data = {
  'key' : 'value0', // what about value1, value2 ?
}

为了解决这个问题,您可能会考虑将具有常见清理键的值聚合到一个数组中,如下所示:

 const data = { 'key' : 'value0', 'key&&&' : 'value1', 'key$%<>' : 'value2', 'foo' : 'value3' } const result = Object.entries(data).reduce((obj, [ key, value ]) => { const sanitizedKey = key.replace(/[.|&;$%@%"<>+]/g, ''); const objValue = obj[ sanitizedKey ] /* Account for conflicting keys after santizing by grouping values in a nested array */ if(objValue) { obj[ sanitizedKey ] = [value].concat(objValue) } else { obj[ sanitizedKey ] = value } return obj; }, {}); console.log(result)

为了扩展@Nina 的回答,这里是完整的表示:

data = [
  {someKey:   1},
  {some0Key:  1},
  {some1Key:  1,
    some2Key:  1},
  {some3Key:  1,
    some4Key:  1,
    some5Key:  1,
    some6Key:  1,
    some7Key:  1,
    some8Key:  1,
    some9Key:  1,
    some10Key: 1,
  },
  {some11Key: 1,
    some12Key: 1,
    some13Key: 1,
    some14Key: 1,
    some15Key: 1,}
];
result = data.map(datum => Object.assign(...Object
    .keys(datum)
    .map(key => ({ [key.replace(/some/g, 'bum')]: datum[key] }))
));

结果:

result === [
  {bumKey:   1},
  {bum0Key:  1},
  {bum1Key:  1,
    bum2Key:  1},
  {bum3Key:  1,
    bum4Key:  1,
    bum5Key:  1,
    bum6Key:  1,
    bum7Key:  1,
    bum8Key:  1,
    bum9Key:  1,
    bum10Key: 1,
  },
  {bum11Key: 1,
    bum12Key: 1,
    bum13Key: 1,
    bum14Key: 1,
    bum15Key: 1,}
];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM