天道酬勤,学无止境

通过键,JavaScript组合JSON数组(Combine json arrays by key, javascript)

问题

我需要结合由两个rest服务提供的两个json数组。 具有相同“ id”的条目属于在一起。

json1 = [{id:1,name:'aaa'},
     {id:5,name:'ccc'},
     {id:3,name:'bbb'}
   ];

 json2 = [{id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
     {id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
     {id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
    ];

我需要通过以下方式(我的模型在angular2中)在javascript中组合/复制/克隆json数组:

json3 = [{id:3,name:'bbb',parameter1:'x', parameter2:'y',   parameter3:'z'},
     {id:1,name:'aaa', parameter1:'u', parameter2:'v', parameter3:'w'},
     {id:5,name:'ccc', parameter1:'q', parameter2:'w', parameter3:'e'}
    ];

有没有办法将它们结合起来? 参数名称未完全定义,需要与可变参数向量一起使用。

我尝试了每个循环混合。 在我看来非常丑陋。

回答1

如果要编写它以便可以接受任意数量的数组,而不仅仅是2个,则可以利用参数,并执行以下操作:

var json1 = [{id:1,name:'aaa'},{id:5,name:'ccc'},{id:3,name:'bbb'}];

var json2 = [{id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
 {id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
 {id:5,parameter1:'q', parameter2:'w', parameter3:'e'}
];

function joinObjects() {
  var idMap = {};
  // Iterate over arguments
  for(var i = 0; i < arguments.length; i++) { 
    // Iterate over individual argument arrays (aka json1, json2)
    for(var j = 0; j < arguments[i].length; j++) {
       var currentID = arguments[i][j]['id'];
       if(!idMap[currentID]) {
          idMap[currentID] = {};
        }
       // Iterate over properties of objects in arrays (aka id, name, etc.)
      for(key in arguments[i][j]) {
          idMap[currentID][key] = arguments[i][j][key];
      }
    }
  }

  // push properties of idMap into an array
  var newArray = [];
  for(property in idMap) {
    newArray.push(idMap[property]);
  }
  return newArray;
}

var json3 = joinObjects(json1, json2);

这是一个工作中的codepen。

回答2

两个单线:

与lodash:

res = _(json1).concat(json2).groupBy('id').map(_.spread(_.assign)).value();

在ES2015中:

res = json2.map(x => Object.assign(x, json1.find(y => y.id == x.id)));
回答3

ES2015 georg的答案很好用;

    json1 = [
    {id:1, test: 0},
    {id:2, test: 0},
    {id:3, test: 0},
    {id:4, test: 0},
    {id:5, test: 0}
];

json2 = [
    {id:1, test: 1},
    {id:3, test: 1},
    {id:5, test: 1}
];

json1.map(x => Object.assign(x, json2.find(y => y.id == x.id)));

结果:

{id:1, test: 1},
{id:2, test: 0},
{id:3, test: 1},
{id:4, test: 0},
{id:5, test: 1}
回答4

 let json1 = [ { id: 1, name: 'aaa' }, { id: 5, name: 'ccc' }, { id: 3, name: 'bbb' } ]; let json2 = [ { id: 3, parameter1: 'x', parameter2: 'y', parameter3: 'z' }, { id: 1, parameter1: 'u', parameter2: 'v', parameter3: 'w' }, { id: 5, parameter1: 'q', parameter2: 'w', parameter3: 'e' } ]; let result = json1.map(obj => { let data = json2.find(item => item.id === obj.id); return {...obj, ...data} }); console.log(result);
 .as-console-wrapper { top: 0; max-height: 100% !important; }
回答5

这是一种方法,您可以首先构建一个以id (稀疏数组)为键的索引,以检测并组合具有匹配id值的对象,然后将它们最终串联回到一个普通数组中:

json3 = json1.concat(json2).reduce(function(index, obj) {
    if (!index[obj.id]) {
        index[obj.id] = obj;
    } else {
        for (prop in obj) {
            index[obj.id][prop] = obj[prop];
        }
    }
    return index;
}, []).filter(function(res, obj) {
    return obj;
});

 json1 = [ {id:1,name:'aaa'}, {id:5,name:'ccc'}, {id:3,name:'bbb'} ]; json2 = [ {id:3,parameter1:'x', parameter2:'y', parameter3:'z'}, {id:1,parameter1:'u', parameter2:'v', parameter3:'w'}, {id:5,parameter1:'q', parameter2:'w', parameter3:'e'} ]; json3 = json1.concat(json2).reduce(function(index, obj) { if (!index[obj.id]) { index[obj.id] = obj; } else { for (prop in obj) { index[obj.id][prop] = obj[prop]; } } return index; }, []).filter(function(res, obj) { return obj; }); document.write('<pre>', JSON.stringify(json3, null, 4), '</pre>');

如果您的浏览器支持Object.assign:

json3 = json1.concat(json2).reduce(function(index, obj) {
    index[obj.id] = Object.assign({}, obj, index[obj.id]);
    return index;
}, []).filter(function(res, obj) {
    return obj;
});
回答6

使用forEachfilter我们可以解决需求。

 vehicleArray1 = [{id:1, name: "a"},{id:2, name: "b"},{id:3, name:"c"}]; vehicleArray2 = [{id:1, type: "two wheeler"},{id:2, type: "four wheeler"},{id:3, type:"six wheeler"}]; var outArr = []; vehicleArray1.forEach(function(value) { var existing = vehicleArray2.filter(function(v, i) { return (v.id == value.id); }); if (existing.length) { value.type = existing[0].type; outArr.push(value) } else { value.type = ''; outArr.push(value); } }); console.log(outArr)
回答7

使用嵌套循环查找相应的元素并将其合并。

for (var i = 0; i < json1.length; i++) {
    var id = json1[i].id;
    for (var j = 0; j < json2.length; j++) {
        if (json2[j].id == id) {
            for (var key in json2[j]) {
                json1[i][key] = json2[j][key];
            }
            break;
        }
    }
}

最后, json1将包含组合的元素。

上面的代码假定的每一个元素json2相匹配的东西json1 。 如果json2可以有额外的元素,那么您以后需要一个附加的循环将这些元素复制到json1

回答8

这应该为您做。 我希望该代码本身有意义。 如果两者都存在,则此示例将始终采用json1值而不是json2值。 如果要更改该值,则需要在最内部的循环中切换对象引用( src[i]obj[j] )。

 // Will take src, and merge in the contents of obj. // Expects an array of objects for both. // Will keep src values in favour of obj values. function extend(src, obj) { // Loop the src, in this case json1 for (var i = 0; i < src.length; i++) { // For every loop of json1, also loop json2 for (var j = 0; j < obj.length; j++) { // If we have matching IDs operate on this pair if (src[i].id == obj[j].id) { // For every key in the object being merged in, // if the key exists in src, ignore new value. // if the doesn't exist in src, take the new value. for (var key in obj[j]) { src[i][key] = src[i].hasOwnProperty(key) ? src[i][key] : obj[j][key]; } // We found our matching pair, so break out of the json2 loop break; } } } return src; } // ------------------------------------------- var json1 = [{ id: 1, name: 'aaa' },{ id: 5, name: 'ccc' },{ id: 3, name: 'bbb' }]; var json2 = [{ id: 3, parameter1: 'x', parameter2: 'y', parameter3: 'z' },{ id: 1, parameter1: 'u', parameter2: 'v', parameter3: 'w' },{ id: 5, parameter1: 'q', parameter2: 'w', parameter3: 'e' }]; var json3 = extend(json1, json2); // --------------------------------------------- var pre = document.getElementById('out'); pre.innerHTML = JSON.stringify(json3);
 <pre id="out"></pre>
回答9

这是使用object-lib的通用解决方案。

好处是您可以完全控制对象的合并方式,这支持嵌套和多个嵌套groupBy。

 // const objectLib = require('object-lib'); const { Merge } = objectLib; const json1 = [{ id: 1, name: 'aaa' }, { id: 5, name: 'ccc' }, { id: 3, name: 'bbb' }]; const json2 = [{ id: 3, parameter1: 'x', parameter2: 'y', parameter3: 'z' }, { id: 1, parameter1: 'u', parameter2: 'v', parameter3: 'w' }, { id: 5, parameter1: 'q', parameter2: 'w', parameter3: 'e' }]; const groupById = Merge({ '[*]': 'id' }); console.log(groupById(json1, json2)); // => [ { id: 1, name: 'aaa', parameter1: 'u', parameter2: 'v', parameter3: 'w' }, { id: 5, name: 'ccc', parameter1: 'q', parameter2: 'w', parameter3: 'e' }, { id: 3, name: 'bbb', parameter1: 'x', parameter2: 'y', parameter3: 'z' } ] const o1 = [{ id: 1, children: [{ type: 'A' }, { type: 'C' }] }, { id: 5 }]; const o2 = [{ id: 1, children: [{ type: 'A' }, { type: 'B' }] }, { id: 3 }]; console.log(groupById(o1, o2)); // => [ { id: 1, children: [ { type: 'A' }, { type: 'C' }, { type: 'A' }, { type: 'B' } ] }, { id: 5 }, { id: 3 } ] const groupByCustom = Merge({ '[*]': 'id', '[*].children[*]': 'type' }); console.log(groupByCustom(o1, o2)); // => [ { id: 1, children: [ { type: 'A' }, { type: 'C' }, { type: 'B' } ] }, { id: 5 }, { id: 3 } ]
 .as-console-wrapper {max-height: 100% !important; top: 0}
 <script src="https://bundle.run/object-lib@2.0.0"></script>

免责声明:我是object-lib的作者

回答10

参数答案的堆栈片段

 const json1 = [{id:1,name:'aaa'},{id:3,name:'bbb'},{id:5,name:'ccc'}]; const json2 = [{id:3,parameters:'xyz'},{id:5,parameters:'qwe'},{id:1,parameters:'uvw'}]; function joinObjects () { const idMap = {}; // Iterate over arguments: for (let i = 0; i < arguments.length; i++) { // Iterate over individual argument arrays, json1, json2: for (let j = 0; j < arguments[i].length; j++) { const currentID = arguments[i][j].id; if (!idMap[currentID]) { idMap[currentID] = {}; } // Iterate over properties of objects in arrays, id, name, etc.: for (key in arguments[i][j]) { idMap[currentID][key] = arguments[i][j][key]; } } } // push properties of idMap into an array: const newArray = []; for (property in idMap) { newArray.push(idMap[property]); } return newArray; } const json3 = joinObjects(json1, json2); document.write(JSON.stringify(json3));
回答11

堆叠两个单线的片段

Lodash:

 const json1 = [{id:1,name:'aaa'},{id:3,name:'bbb'},{id:5,name:'ccc'}]; const json2 = [{id:3,parameters:'xyz'},{id:5,parameters:'qwe'},{id:1,parameters:'uvw'}]; const result = _(json1).concat(json2).groupBy('id').map(_.spread(_.assign)).value(); document.write(JSON.stringify(result));
 <script src= "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js"></script>

Object.assign() ,ECMAScript 2015:

 const json1 = [{id:1,name:'aaa'},{id:3,name:'bbb'},{id:5,name:'ccc'}]; const json2 = [{id:3,parameters:'xyz'},{id:5,parameters:'qwe'},{id:1,parameters:'uvw'}]; const result = json1.map(x=> Object.assign(x, json2.find(y=> y.id === x.id))); document.write(JSON.stringify(result));
回答12

堆栈片段的减少连接的答案

Array.prototype.reduce和匹配的ID:
首先将两个数组连接成一个数组,然后检测并合并具有匹配ID的对象。 最后过滤掉所有null值。

 const json1 = [{id:1,name:'aaa'},{id:3,name:'bbb'},{id:5,name:'ccc'}]; const json2 = [{id:3,parameters:'xyz'},{id:5,parameters:'qwe'},{id:1,parameters:'uvw'}]; const json5 = json1.concat(json2); document.write('json5:<br>'+JSON.stringify(json5)+'<br><br>Result:<br>'); const result = json5.reduce((accumulator, obj) => { if (!accumulator[obj.id]) { accumulator[obj.id] = obj; } else { for (proprty in obj) { accumulator[obj.id][proprty] = obj[proprty];} } return accumulator; }, []).filter(x => x); document.write(JSON.stringify(result));

使用Array.prototype.reduce和Object.assign:

 const json1 = [{id:1,name:'aaa'},{id:3,name:'bbb'},{id:5,name:'ccc'}]; const json2 = [{id:3,parameters:'xyz'},{id:5,parameters:'qwe'},{id:1,parameters:'uvw'}]; const result = json1.concat(json2).reduce((accumulator, obj) => { accumulator[obj.id] = Object.assign({}, accumulator[obj.id], obj); return accumulator; }, []).filter(x => x); document.write(JSON.stringify(result));

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 将键数组和值数组合并到JavaScript中的对象中(Merge keys array and values array into an object in JavaScript)
    问题 我有: var keys = [ "height", "width" ]; var values = [ "12px", "24px" ]; 我想将其转换为该对象: { height: "12px", width: "24px" } 在Python中,有一个简单的成语dict(zip(keys,values)) 。 jQuery或纯JavaScript中是否有类似的东西,还是我必须长期这样做? 回答1 简单的JS函数将是: function toObject(names, values) { var result = {}; for (var i = 0; i < names.length; i++) result[names[i]] = values[i]; return result; } 当然,您实际上也可以实现zip之类的功能,因为JS支持更高阶的类型,这使这些函数语言主义变得容易:D 回答2 使用Array reduce的最简单的ES6一线解决方案: const keys = ['height', 'width']; const values = ['12px', '24px']; const merged = keys.reduce((obj, key, index) => ({ ...obj, [key]: values[index] }), {}); 回答3
  • json_encode不保留顺序(json_encode not preserving order)
    问题 我在PHP中有一个多维数组: Array ( [1] => Array ( [19] => Array ( [type] => 2 ) [6] => Array ( [type] => 4 ) [12] => Array ( [type] => 3 ) ) ) 当我通过以下方式在javascript中对这个数组进行json_encode时: var jsonArray = <?php echo json_encode($above_array); ?>; 我得到: Object ( [1] => Object ( [6] => Object ( [type] => 2 ) [12] => Object ( [type] => 4 ) [19] => Object ( [type] => 3 ) ) ) 我想保留第一个订单,而不是第二个订单。 回答1 有关StackOverflow的问题,JavaScript是否保证对象属性顺序? 简而言之,答案是否定的,不是。 因此,当将PHP数组转换为Javascript对象时,键顺序将不会保留。 PHP和Javascript之间数组的主要区别在于,后者只能容纳从零开始的连续整数键。 因此,并非总是可能将PHP数组转换为Javascript数组。 让我们看几个例子: // example 1 echo json_encode(array(0
  • 将具有数字键的JavaScript对象转换为数组(Converting JavaScript object with numeric keys into array)
    问题 我有一个像这样的对象作为服务器的JSON响应返回: {"0":"1","1":"2","2":"3","3":"4"} 我想将其转换为如下所示的JavaScript数组: ["1","2","3","4"] 有没有最好的方法来做到这一点? 无论我在哪里阅读,人们都在使用复杂的循环逻辑。 那么,有替代方法可以做到这一点吗? 回答1 jQuery的$ .map实际上非常简单 var arr = $.map(obj, function(el) { return el }); 小提琴 在没有jQuery的情况下几乎一样容易,将键转换为数组,然后使用Array.map映射回值 var arr = Object.keys(obj).map(function(k) { return obj[k] }); 小提琴 假设它已经被解析为javascript对象,并且实际上不是JSON(JSON是一种字符串格式),在这种情况下,还需要通过JSON.parse进行运行。 在ES2015中,有一个Object.values可以解救,这使它轻而易举 var arr = Object.values(obj); 回答2 var json = '{"0":"1","1":"2","2":"3","3":"4"}'; var parsed = JSON.parse(json); var arr = []
  • 您如何通过JSON.stringify ES6 Map?(How do you JSON.stringify an ES6 Map?)
    问题 我想开始使用ES6 Map而不是JS对象,但由于无法弄清楚如何对地图进行JSON.stringify()而被拒之门外。 我的键保证是字符串,并且我的值将始终列出。 我真的必须编写包装方法来序列化吗? 回答1 JSON.stringify和JSON.parse支持第二个参数。 replacer和reviver 。 通过以下的replacer和reviver,可以添加对本机Map对象的支持,包括深度嵌套的值 function replacer(key, value) { if(value instanceof Map) { return { dataType: 'Map', value: Array.from(value.entries()), // or with spread: value: [...value] }; } else { return value; } } function reviver(key, value) { if(typeof value === 'object' && value !== null) { if (value.dataType === 'Map') { return new Map(value.value); } } return value; } 用法: const originalValue = new Map([['a', 1]
  • JavaScript是否保证对象属性顺序?(Does JavaScript guarantee object property order?)
    问题 如果我创建这样的对象: var obj = {}; obj.prop1 = "Foo"; obj.prop2 = "Bar"; 生成的对象会始终看起来像这样吗? { prop1 : "Foo", prop2 : "Bar" } 也就是说,这些属性的顺序是否与我添加它们的顺序相同? 回答1 自ES2015起,对象的迭代顺序遵循一组特定的规则,但不(始终)遵循插入顺序。 简而言之,迭代顺序是字符串键的插入顺序和数字键的升序的组合: // key order: 1, foo, bar const obj = { "foo": "foo", "1": "1", "bar": "bar" } 使用数组或Map对象可能是实现此目的的更好方法。 Map与Object有一些相似之处,并保证按插入顺序对键进行迭代,无一例外: Map中的键是有序的,而添加到对象中的键则没有顺序。 因此,在对其进行迭代时,Map对象将按插入顺序返回键。 (请注意,在ECMAScript 2015规范中,对象确实保留了字符串和符号键的创建顺序,因此仅使用字符串键遍历对象即会按插入顺序产生键) 请注意,在ES2015之前根本无法保证对象中的属性顺序。 ECMAScript第三版(pdf)中对象的定义: 4.3.3对象对象是对象类型的成员。 它是属性的无序集合,每个属性都包含原始值,对象或函数。
  • 如何将键/值对添加到JavaScript对象?(How can I add a key/value pair to a JavaScript object?)
    问题 这是我的对象文字: var obj = {key1: value1, key2: value2}; 如何将具有value3字段key3添加到对象? 回答1 有两种向对象添加新属性的方法: var obj = { key1: value1, key2: value2 }; 使用点表示法: obj.key3 = "value3"; 使用方括号表示法: obj["key3"] = "value3"; 当您知道属性名称时,将使用第一种形式。 动态确定属性名称时,使用第二种形式。 像这个例子一样: var getProperty = function (propertyName) { return obj[propertyName]; }; getProperty("key1"); getProperty("key2"); getProperty("key3"); 可以使用以下任意一种来构造真实的JavaScript数组: 数组文字表示法: var arr = []; 数组构造器符号: var arr = new Array(); 回答2 2017年答案: Object.assign() Object.assign(dest,src1,src2,...)合并对象。 它用(多少个)源对象的属性和值覆盖dest ,然后返回dest 。 Object.assign(
  • 如何通过键合并两个对象值(How to merge two object values by keys)
    问题 尝试查看是否有任何JavaScript库功能可以合并两个json对象的特定键的值 var x ={ "student-marks":{'math':1,'physics':5} }; var y ={ "student-marks":{'chemistry':3,'history':2} }; 使用$ .extend和$ .merge给出以下结果 $.extend({},x,y) leads to { "student-marks":{'chemistry':3,'history':2} } $.merge(x,y) leads to { "student-marks":{'math':1,'physics':2} } 我所寻找的是{ { "student-marks":{'math':1,'physics':5, 'chemistry':3,'history':2} }‍ 回答1 你想要一个深层的延伸 $.extend(true, {}, x, y); 请参阅jQuery.extend([deep],target,object1 [,objectN])的文档 回答2 不依赖jQuery的简单javascript函数将帮助您合并具有嵌套对象的两个JSON对象。 function mergeJSON(source1,source2){ /* * Properties from
  • 如何在javascript中进行深度克隆(How to Deep clone in javascript)
    问题 您如何深度克隆JavaScript对象? 我知道有各种基于JSON.parse(JSON.stringify(o))和$.extend(true, {}, o)等框架的函数$.extend(true, {}, o)但是我不想使用这样的框架。 创建深度克隆的最优雅或最有效的方法是什么。 我们确实关心边缘情况,例如克隆数组。 不打破原型链,处理自我参考。 我们不在乎是否支持DOM对象的复制,就像这样,因为存在.cloneNode 。 由于我主要想在node.js使用深度克隆,因此可以使用V8引擎的ES5功能。 [编辑] 在有人建议我之前,先通过原型继承对象创建副本与克隆副本之间存在明显的区别。 前者使原型链一团糟。 [进一步编辑] 阅读您的答案后,我发现了一个令人讨厌的发现,即克隆整个对象是一个非常危险且困难的游戏。 以下面的基于闭包的对象为例 var o = (function() { var magic = 42; var magicContainer = function() { this.get = function() { return magic; }; this.set = function(i) { magic = i; }; } return new magicContainer; }()); var n = clone(o); // how to
  • 按键对JavaScript对象进行排序(Sort JavaScript object by key)
    问题 我需要按键对JavaScript对象进行排序。 因此,以下内容: { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' } 会成为: { 'a' : 'dsfdsfsdf', 'b' : 'asdsad', 'c' : 'masdas' } 回答1 此问题的其他答案已过时,从未与实现现实相匹配,并且由于ES6 / ES2015规范已发布而正式变得不正确。 请参阅Axel Rauschmayer的“探索ES6”中有关属性迭代顺序的部分: 所有遍历属性键的方法都以相同的顺序进行: 首先是所有数组索引,按数字排序。 然后,所有字符串键(不是索引)均按照其创建顺序排列。 然后按创建顺序排列所有符号。 所以,是的,JavaScript对象其实都是有序的,他们的键的顺序/属性是可以改变的。 以下是按字母/属性按字母顺序对对象进行排序的方法: const unordered = { 'b': 'foo', 'c': 'bar', 'a': 'baz' }; console.log(JSON.stringify(unordered)); // → '{"b":"foo","c":"bar","a":"baz"}' const ordered = Object.keys(unordered).sort().reduce( (obj, key)
  • JavaScript关联数组到JSON(JavaScript associative array to JSON)
    问题 如何将JavaScript关联数组转换为JSON? 我尝试了以下方法: var AssocArray = new Array(); AssocArray["a"] = "The letter A" console.log("a = " + AssocArray["a"]); // result: "a = The letter A" JSON.stringify(AssocArray); // result: "[]" 回答1 数组只能包含带有数字键的条目(数组也是对象,但您实际上不应该将它们混合使用)。 如果将数组转换为JSON,则该过程将仅考虑数值属性。 其他属性只是被忽略,这就是为什么您得到一个空数组的原因。 如果您看一下数组的length ,则可能更明显: > AssocArray.length 0 通常被称为“关联数组”的实际上只是JS中的一个对象: var AssocArray = {}; // <- initialize an object, not an array AssocArray["a"] = "The letter A" console.log("a = " + AssocArray["a"]); // "a = The letter A" JSON.stringify(AssocArray); // "{"a":"The letter A"}"
  • 排序对象属性和JSON.stringify(sort object properties and JSON.stringify)
    问题 我的应用程序包含大量对象,我将它们进行字符串化并将其保存到磁盘。 不幸的是,当数组中的对象被操纵并且有时被替换时,对象上的属性以不同的顺序列出(它们的创建顺序?)。 当我在数组上执行JSON.stringify()并将其保存时,一个diff显示以不同顺序列出的属性,当尝试使用diff和合并工具进一步合并数据时,这很烦人。 理想情况下,我想在执行字符串化之前或作为字符串化操作的一部分,按字母顺序对对象的属性进行排序。 有很多代码可以在多个地方操纵数组对象,而更改它们以始终以显式顺序创建属性将很困难。 建议将是最欢迎的! 一个简洁的例子: obj = {}; obj.name="X"; obj.os="linux"; JSON.stringify(obj); obj = {}; obj.os="linux"; obj.name="X"; JSON.stringify(obj); 这两个string化调用的输出是不同的,并且显示在我的数据差异中,但是我的应用程序并不关心属性的顺序。 这些对象以多种方式和位置构造。 回答1 更简单,现代且当前受浏览器支持的方法如下: JSON.stringify(sortMyObj, Object.keys(sortMyObj).sort()); 但是,此方法会删除所有未引用的嵌套对象,并且不适用于数组内的对象。 如果您想要类似以下输出的内容
  • 如何在JavaScript中将Object{}转换为键值对的Array[]?
    任务是使用JavaScript将Object{}转换为键值对的Array[]。 介绍:JavaScript中的对象是最重要的数据类型, 它构成了现代JavaScript的基础。这些对象与JavaScript的原始数据类型(数字, 字符串, 布尔值, 空值, 未定义和符号)有很大不同。对象更加复杂, 每个对象可以包含这些原始数据类型以及参考数据类型的任意组合, 而数组是用于存储不同元素的单个变量。当我们要存储元素列表并通过单个变量访问它们时, 通常使用它。 我们可以使用以下讨论的方法将Object {}转换为键值对的Array []: 方法1:在这个方法中,我们将使用Object.keys()和map()来实现这一点。 方法:通过使用Object.keys(), 我们从Object中提取键, 然后将此键传递给map()函数, 该函数将键和对应的值映射为数组, 如以下示例中所述。 语法如下: Object.keys(obj) 参数: obj:这是要返回其可枚举属性的对象。 map(function callback(currentValue[, index[, array]]){ // Return element for new_array } 参数: callback:产生新数组元素的函数 例子: <script> // An Object var obj = { "1" : 5
  • 在PHP中,如何更改数组元素的键?(In PHP, how do you change the key of an array element?)
    问题 我有一个形式为key => value的关联数组,其中key是一个数字值,但是它不是一个连续的数字值。 密钥实际上是一个ID号,而值是一个计数。 这在大多数情况下都很好,但是我想要一个函数,该函数可获取数组的可读名称并将其用于键,而无需更改其值。 我没有看到执行此操作的函数,但是我假设我需要提供旧键和新键(我都拥有)并转换数组。 有没有一种有效的方法可以做到这一点? 回答1 $arr[$newkey] = $arr[$oldkey]; unset($arr[$oldkey]); 回答2 您执行此操作并保留数组顺序的方法是,将数组键放入单独的数组中,在该数组中查找并替换键,然后将其与值重新组合在一起。 这是一个执行此操作的函数: function change_key( $array, $old_key, $new_key ) { if( ! array_key_exists( $old_key, $array ) ) return $array; $keys = array_keys( $array ); $keys[ array_search( $old_key, $keys ) ] = $new_key; return array_combine( $keys, $array ); } 回答3 如果您的array是通过数据库查询构建的,则可以直接从mysql语句更改键:
  • 在JavaScript中存储key => value数组的最佳方法?(Best way to store a key=>value array in JavaScript?)
    问题 在JavaScript中存储key=>value数组的最佳方法是什么,如何循环遍历? 每个元素的键应为标签,例如{id}或仅是id ,其值应为id的数值。 它应该是现有javascript类的元素,或者是可以通过该类轻松引用的全局变量。 可以使用jQuery。 回答1 这就是一个JavaScript对象: var myArray = {id1: 100, id2: 200, "tag with spaces": 300}; myArray.id3 = 400; myArray["id4"] = 500; 您可以使用for..in循环遍历它: for (var key in myArray) { console.log("key " + key + " has value " + myArray[key]); } 另请参阅:处理对象(MDN)。 在ECMAScript6中,还有Map(请参阅此处的浏览器兼容性表): 对象具有原型,因此地图中包含默认键。 自ES5开始,可以通过使用map = Object.create(null)来绕过此方法,但很少这样做。 对象的键是字符串和符号,其中键可以是Map的任何值。 您可以轻松获取地图的大小,而不必手动跟踪对象的大小。 回答2 如果我正确理解您的意见: var hash = {}; hash['bob'] = 123; hash[
  • PHP“ php:// input”与$ _POST(PHP “php://input” vs $_POST)
    问题 当与来自JQuery的Ajax请求进行交互时,我被指示使用方法php://input而不是$_POST 。 我不了解使用此方法与$_POST或$_GET全局方法的好处。 回答1 原因是php://input在请求的HTTP标头之后返回所有原始数据,而与内容类型无关。 PHP的超全局$_POST ,只应该总结的数据要么是 application/x-www-form-urlencoded (用于简单表单发布的标准内容类型)或 multipart/form-data (主要用于文件上传) 这是因为这些是用户代理必须支持的唯一内容类型。 因此,服务器和PHP传统上不希望接收任何其他内容类型(这并不意味着它们不能)。 因此,如果您只是简单地发布旧的HTML form ,则请求看起来像这样: POST /page.php HTTP/1.1 key1=value1&key2=value2&key3=value3 但是,如果您经常使用Ajax,那么这种可能性还包括使用类型(字符串,整数,布尔值)和结构(数组,对象)交换更复杂的数据,因此在大多数情况下,JSON是最佳选择。 但是带有JSON有效负载的请求看起来像这样: POST /page.php HTTP/1.1 {"key1":"value1","key2":"value2","key3":"value3"}
  • 如何在现有的JavaScript函数中添加JavaScript键盘快捷键?(How can I add a JavaScript keyboard shortcut to an existing JavaScript Function?)
    问题 这是我的代码: function pauseSound() { var pauseSound = document.getElementById("backgroundMusic"); pauseSound.pause(); } 我想在此代码中添加键盘快捷键,如何做到这一点,以便当单击按钮时也可以执行该功能? 试图添加一个else if语句,但是它不起作用,有什么想法吗? function doc_keyUp(e) { if (e.ctrlKey && e.keyCode == 88) { pauseSound(); } else if (e.ctrlKey && e.keyCode == 84) { playSound(); } } 回答1 文档的keyup事件的事件处理程序似乎是一个合适的解决方案。 注意:不推荐使用KeyboardEvent.keyCode而推荐使用key 。 // define a handler function doc_keyUp(e) { // this would test for whichever key is 40 (down arrow) and the ctrl key at the same time if (e.ctrlKey && e.key === 'ArrowDown') { // call your function to
  • JavaScript中的地图与对象(Map vs Object in JavaScript)
    问题 我刚刚发现了此功能: 映射:映射对象是简单的键/值映射。 那让我感到困惑。 常规JavaScript对象是字典,那么Map与字典有何不同? 从概念上讲,它们是相同的(根据有关Stackoverflow的另一个问题) 该文档也无济于事: 映射对象是键/值对的集合,其中键和值都可以是任意ECMAScript语言值。 一个唯一的键值只能出现在地图集合中的一个键/值对中。 使用创建地图时选择的比较算法来区分的不同键值。 Map对象可以按插入顺序迭代其元素。 映射对象必须使用哈希表或其他机制来实现,这些机制通常提供的访问时间与集合中元素的数量成线性关系。 本Map对象规范中使用的数据结构仅用于描述Map对象所需的可观察语义。 它并非旨在成为可行的实施模型。 …对我来说听起来仍然像是一个对象,所以很明显我错过了一些东西。 为什么JavaScript会获得一个(得到良好支持的)Map对象? 它有什么作用? 回答1 根据mozilla: Map对象可以按插入顺序对其元素进行迭代-for..of循环将为每次迭代返回[key,value]数组。 和 对象与Maps相似,两者都可以让您将键设置为值,检索这些值,删除键并检测是否在键处存储了某些内容。 因此,对象在历史上一直被用作地图; 但是,对象和地图之间存在重要差异,因此可以更好地使用地图。 对象具有原型,因此地图中包含默认键。 但是
  • JSON.stringify是否在属性上没有引号?(JSON.stringify without quotes on properties?)
    问题 我正在使用使用不正确的JSON格式的服务(属性周围没有双引号)。 所以我需要发送 { name: "John Smith" }而不是{ "name": "John Smith" } 无法更改此格式,因为这不是我的服务。 有谁知道像上面这样格式化JavaScript对象的字符串化路由? 回答1 在大多数情况下,此简单的正则表达式解决方案可取消对JSON属性名称的引用: const object = { name: 'John Smith' }; const json = JSON.stringify(object); // {"name":"John Smith"} console.log(json); const unquoted = json.replace(/"([^"]+)":/g, '$1:'); console.log(unquoted); // {name:"John Smith"} 极端情况: var json = '{ "name": "J\\":ohn Smith" }' json.replace(/\\"/g,"\uFFFF"); // U+ FFFF json = json.replace(/"([^"]+)":/g, '$1:').replace(/\uFFFF/g, '\\\"'); // '{ name: "J\":ohn Smith" }'
  • 将数组转换为对象(Convert Array to Object)
    问题 转换的最佳方法是什么: ['a','b','c'] 到: { 0: 'a', 1: 'b', 2: 'c' } 回答1 ECMAScript 6引入了易于填充的Object.assign: Object.assign()方法用于将所有可枚举的自身属性的值从一个或多个源对象复制到目标对象。 它将返回目标对象。 Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"} 数组的自身length属性不会被复制,因为它不可枚举。 另外,您可以在对象上使用ES8传播语法以达到相同的结果: { ...['a', 'b', 'c'] } 回答2 具有这样的功能: function toObject(arr) { var rv = {}; for (var i = 0; i < arr.length; ++i) rv[i] = arr[i]; return rv; } 您的数组已经或多或少只是一个对象,但是对于整数命名的属性,数组确实具有一些“有趣”的特殊行为。 以上将为您提供一个简单的对象。 编辑哦,您也可能要考虑数组中的“孔”: function toObject(arr) { var rv = {}; for (var i = 0; i < arr.length; ++i) if (arr[i] !== undefined)
  • 如何检查JavaScript是否在某个数组索引处存在值?(How do I check in JavaScript if a value exists at a certain array index?)
    问题 这将用于测试位置index处的值是否存在,或者是否有更好的方法: if(arrayName[index]==""){ // do stuff } 回答1 从概念上讲,JavaScript中的数组包含array.length元素,从array[0]开始直到array[array.length - 1] 。 如果i在0到array.length - 1含)之间,则将索引为i的数组元素定义为该数组的一部分。 如果我不在此范围内,则不在数组中。 因此,从概念上讲,数组是线性的,从零开始并达到最大值,而没有任何机制可以使该范围内的“间隙”不存在任何条目。 要找出给定位置索引(索引为0或正整数)是否存在值,您只需使用 if (i >= 0 && i < array.length) { // it is in array } 现在,在引擎盖下,JavaScript引擎几乎肯定不会像这样线性地和连续地分配数组空间,因为在动态语言中这没有多大意义,并且对于某些代码而言效率不高。 它们可能是哈希表或策略的某种混合体,并且数组的未定义范围可能未分配给它们自己的内存。 尽管如此,JavaScript的语言想要的本阵列array.length n的具有n个成员和它们被命名为0到n - 1,和在该范围内的任何是阵列的一部分。 但是,您可能想要知道的是数组中的值是否确实已定义-即不是undefined 。