Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在对象数组中高效地重命名/重新映射javascript/json对象键_Javascript_Arrays_Json_Javascript Objects - Fatal编程技术网

在对象数组中高效地重命名/重新映射javascript/json对象键

在对象数组中高效地重命名/重新映射javascript/json对象键,javascript,arrays,json,javascript-objects,Javascript,Arrays,Json,Javascript Objects,我有一些类似这样的结构化JSON数据。让我们假设这是可互换的,通过: 我需要它看起来像这样,将title重新映射到name,并将uid映射到id,结果如下: [ { "name": "pineapple", "id": "ab982d34c98f" }, { "name": "carrots", "id": "6f12e6ba45ec" } ] 最明显的做法是: str = '[{"title":

我有一些类似这样的结构化JSON数据。让我们假设这是可互换的,通过:

我需要它看起来像这样,将
title
重新映射到
name
,并将
uid
映射到
id
,结果如下:

[
    {
        "name": "pineapple",
        "id": "ab982d34c98f"
    },
    {
        "name": "carrots",
        "id": "6f12e6ba45ec"
    }
]
最明显的做法是:

str = '[{"title": "pineapple","uid": "ab982d34c98f"},{"title": "carrots", "uid": "6f12e6ba45ec"}]';

var arr = JSON.parse(str);
for (var i = 0; i<arr.length; i++) {
    arr[i].name = arr[i].title;
    arr[i].id = arr[i].uid;
    delete arr[i].title;
    delete arr[i].uid;
}
str='[{“title”:“菠萝”,“uid”:“ab982d34c98f”},{“title”:“胡萝卜”,“uid”:“6f12e6ba45ec”}];
var arr=JSON.parse(str);
对于(var i=0;i
根据下面讨论的不同基准,最快的解决方案适用于:

var arr = []
jsonObj.forEach(function(item) { arr.push({"name": item.title, "id" : item.uid }); });
在使用navite函数和非navite函数之间总是存在争论。如果我没记错的话,我认为它们比下划线更快,因为它们使用非本机函数进行键操作

然而,不同的浏览器有时会产生非常不同的结果。我总是寻找最好的平均值

对于基准测试,您可以查看以下内容:


正如我在评论中已经提到的,如果可以对对象的值进行某些假设,可以使用正则表达式替换键,例如:

var arr = JSON.parse(str, function(prop, value) {
   switch(prop) {
     case "title":
        this.name = value;
        return;
     case "uid":
        this.id = value;
        return;
     default:
        return value;
   }
});
它没有“干净”,但它可能会更快地完成工作


如果必须解析JSON,则可以采用更结构化的方法,并且可以避免对数组进行额外的传递。这可能取决于引擎如何实现
JSON.parse
(可能他们首先解析整个字符串,然后使用reviver函数进行第二次传递,在这种情况下,您不会获得任何优势)


基准测试,使用下面的Node.js脚本测试3次:

fs = require('fs');
fs.readFile('test.json', 'utf8', function (err, data) {
    if (err) {
        return console.log(err);
    }
    console.log(new Date().getTime() + ": Beginning regex rename test");
    var str = data.replace(/"title":/g, '"name":');
    str = str.replace(/"uid":/g, '"id":');
    JSON.parse(str);
    console.log(new Date().getTime() + ": Regex rename complete");
    console.log(new Date().getTime() + ": Beginning parse and remap in for loop test");
    var arr = JSON.parse(data);
    for (var i = 0; i < arr.length; i++) {
        arr[i].name = arr[i].title;
        arr[i].id = arr[i].uid;
        delete arr[i].title;
        delete arr[i].uid;
    }
    console.log(new Date().getTime() + ": For loop remap complete");
    console.log(new Date().getTime() + ": Beginning reviver function test");
    var arr = JSON.parse(data, function (prop, value) {
        switch (prop) {
            case "title":
                this.name = value;
                return;
            case "uid":
                this.id = value;
                return;
            default:
                return value;
        }
    });
    console.log(new Date().getTime() + ": Reviver function complete");
});
似乎正则表达式(在本例中)是最有效的,但是


测试脚本,加载100230行OP的示例JSON:

var repl = orig.map(function(obj) {
    return {
        name: obj.title,
        id: obj.uid
    }
})
fs=require('fs');
fs.readFile('test.json','utf8',函数(err,data){
如果(错误){
返回console.log(err);
}
log(new Date().getTime()+“:开始正则表达式重命名测试”);
var str=data.replace(/“title”:/g,““name”:”);
str=str.replace(/“uid”:/g,““id”:”);
JSON.parse(str);
log(new Date().getTime()+“:Regex rename complete”);
log(new Date().getTime()+“:开始解析并重新映射for循环测试”);
var arr=JSON.parse(数据);
对于(变量i=0;i
很久以前就提出了这个问题,从那时起,我开始习惯于使用它来完成工作,更多的是为了代码的稳定性和清洁度,而不是性能。虽然它肯定不是性能最好的,但它看起来很棒:

let replaceKeyInObjectArray = (a, r) => a.map(o => 
    Object.keys(o).map((key) => ({ [r[key] || key] : o[key] })
).reduce((a, b) => Object.assign({}, a, b)))
如果您需要更灵活(且与ES6兼容)的功能,请尝试:

e、 g


如果你想让它更具可重用性,也许这是一个不错的方法

函数重设键(arr,查找){
对于(变量i=0;iconsole.log(已转换);
这里是对OP建议使用
map()
的另一种理解,目的是为了清晰(而不是性能)

当只有一个parm传递给函数,并且函数体中只有一个语句时,这将使用快捷语法

根据您使用不同语言的lambda表达式的历史,这种形式可能与您产生共鸣,也可能与您不产生共鸣

在箭头函数快捷方式语法中返回对象文字时要小心。不要忘记对象文字周围的附加参数!

使用ES6:

const renameFieldInArrayOfObjects = (arr, oldField, newField) => {
  return arr.map(s => {
    return Object.keys(s).reduce((prev, next) => {
      return next === oldField
        ? {...prev, [newField]: s[next]}
        : {...prev, [next]: s[next]}
    }, {})
  })
}
使用ES7:

const data = [
  {
    title: 'pineapple',
    uid: 'ab982d34c98f',
  },
  {
    title: 'carrots',
    uid: '6f12e6ba45ec',
  },
];

您可以使用名为的npm包

您的数据:

const map = {
  item: {
    name: 'title',
    id: 'uid',
  },
};
您的映射:

const DataTransform = require("node-json-transform").DataTransform;
const dataTransform = DataTransform(data, map);
const result = dataTransform.transform();
console.log(result);
并使用该软件包:

[
  {
    name: 'pineapple',
    id: 'ab982d34c98f'
  },
  {
    name: 'carrots',
    id: '6f12e6ba45ec'
  }
]
结果:

function replaceElem(value, replace, str) {
            while (str.indexOf(value) > -1) {
                str = str.replace(value, replace);
            }
            return str;
        }
也许这不是最好的表演方式,但它相当优雅

var value = "tittle";
var replace = "name";
replaceElem(value, replace, str);
从main打电话来


考虑创建一个带有<代码> {从,to }的数组
pairs,然后使用函数遍历
arr
FYI,此问题与JSON无关,除非您希望执行字符串处理以更改键。您希望如何在不遍历数组的情况下修改数组中的每个对象?这没有意义。为什么需要重新映射?您可以比较正则表达式替换的方式,例如,
str=str.replace(/“title”:/g,“name”:’)当然,这会对对象可以拥有的值做出某些假设,但这很容易做到,所以为什么不尝试一下呢?为什么这会更有效?请详细说明。根据您的基准测试,
Array.map
实际上比Chrome和Safari中的
for
循环要慢。所以,这并不是问题“没有真正的帮助。此外,我最终将在Node.js中构建这个,并将依赖于V8.FYI,这是针对这个特定问题的另一个性能测试。我认为结果非常清楚。@remus如果您的问题与NodeJS相关,那么这是另一个故事,这就是为什么我提到了跨浏览器的平均值。哎哟“跨浏览器平均值”表明您的解决方案速度较慢。但看起来正则表达式是最快的——我只是用一个简单的“否”来测试它
const renameFieldInArrayOfObjects = (arr, oldField, newField) => {
  return arr.map(s => {
    return Object.keys(s).reduce((prev, next) => {
      if(next === oldField) { 
        prev[newField] = s[next]
      } else { 
        prev[next] = s[next] 
      }
      return prev
    }, {})
  })
}
const renameFieldInArrayOfObjects = (arr, oldField, newField) => {
  return arr.map(s => {
    return Object.keys(s).reduce((prev, next) => {
      return next === oldField
        ? {...prev, [newField]: s[next]}
        : {...prev, [next]: s[next]}
    }, {})
  })
}
const data = [
  {
    title: 'pineapple',
    uid: 'ab982d34c98f',
  },
  {
    title: 'carrots',
    uid: '6f12e6ba45ec',
  },
];
const map = {
  item: {
    name: 'title',
    id: 'uid',
  },
};
const DataTransform = require("node-json-transform").DataTransform;
const dataTransform = DataTransform(data, map);
const result = dataTransform.transform();
console.log(result);
[
  {
    name: 'pineapple',
    id: 'ab982d34c98f'
  },
  {
    name: 'carrots',
    id: '6f12e6ba45ec'
  }
]
function replaceElem(value, replace, str) {
            while (str.indexOf(value) > -1) {
                str = str.replace(value, replace);
            }
            return str;
        }
var value = "tittle";
var replace = "name";
replaceElem(value, replace, str);