Подтвердить что ты не робот

Объединение или объединение JSON на node.js без jQuery

У меня есть несколько JSON, таких как

var object1 = {name: "John"};
var object2 = {location: "San Jose"};

Они не гнездятся или что-то в этом роде. Просто в основном разные поля. Мне нужно объединить их в один JSON в node.js следующим образом:

{name: "John", location: "San Jose"}

Я могу использовать jQuery просто отлично. Вот пример работы в браузере:

http://jsfiddle.net/qhoc/agp54/

Но если я делаю это в node.js, я не хочу загружать jQuery (который немного перегружен, плюс node.js 'jQuery не работает на моей машине Windows).

Итак, есть простой способ сделать что-то похожее на $.extend() без jQuery?

4b9b3361

Ответ 1

Нормальная петля?

function extend(target) {
    var sources = [].slice.call(arguments, 1);
    sources.forEach(function (source) {
        for (var prop in source) {
            target[prop] = source[prop];
        }
    });
    return target;
}

var object3 = extend({}, object1, object2);

Это базовая отправная точка. Возможно, вы захотите добавить такие вещи, как проверка hasOwnProperty, или добавить некоторую логику для обработки случая, когда несколько исходных объектов имеют свойство с тем же идентификатором.

Здесь рабочий пример.

Боковое примечание: то, что вы называете "JSON", на самом деле являются обычными объектами JavaScript. JSON - это просто текстовый формат, который разделяет некоторый синтаксис с JavaScript.

Ответ 2

Существует также встроенный util._extend:

var extend = require('util')._extend
var o = extend({}, {name: "John"});
extend(o,  {location: "San Jose"});

Он не делает глубокую копию и допускает только два аргумента за раз, но встроен. Я видел это на вопрос о клонировании объектов в node: fooobar.com/questions/41612/....

Если вы обеспокоены использованием метода "private", вы всегда можете проксировать его:

// myutil.js
exports.extend = require('util')._extend;

и замените его своей собственной реализацией, если он когда-либо исчезнет. Это (приблизительно) их реализация:

exports.extend = function(origin, add) {
    if (!add || (typeof add !== 'object' && add !== null)){
        return origin;
    }

    var keys = Object.keys(add);
    var i = keys.length;
    while(i--){
        origin[keys[i]] = add[keys[i]];
    }
    return origin;
};

Ответ 3

Подчеркнуть extend - это самый простой и быстрый способ достичь этого, как прокомментировал Джеймс.

Вот пример с использованием подчеркивания:

var _ = require('underscore'), // npm install underscore to install
  object1 = {name: "John"},
  object2 = {location: "San Jose"};

var target = _.extend(object1, object2);

объект 1 получит свойства объекта2 и будет возвращен и назначен целевому. Вы могли бы сделать это так же, в зависимости от того, изменяете ли вы объект object1:

var target = {};
_.extend(target, object1, object2);

Ответ 4

Вы должны использовать Object.assign()"; нет необходимости изобретать велосипед для такого простого случая мелкого слияния.

Метод Object.assign() используется для копирования значений всех перечислимых собственных свойств из одного или нескольких исходных объектов в целевой объект. Он вернет целевой объект.

var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed

Даже люди из Node.js говорят так:

_extend никогда не предназначался для использования за пределами внутренних модулей NodeJS. Сообщество нашло и использовало его в любом случае. Он устарел и не должен использоваться в новом коде. JavaScript поставляется с очень похожими встроенными функциями через Object.assign.

Тем не менее, имейте в виду, что Object.assign не работает с версиями 0.X Node.js. Если вы работаете с одной из этих версий, вы можете использовать require("util")._extend, как показано в ссылке выше - у вас не должно быть проблем с ней, поскольку он больше не будет обновляться для этих старых версий.


PS: Если вы действительно заинтересованы в глубоком объединении (в котором внутренние данные объекта - на любой глубине - рекурсивно объединены), вы можете использовать пакеты, такие как deepmerge, assign-deep или lodash.merge, которые довольно малы и просты в использовании.

Ответ 5

Используйте merge.

$ npm install merge

Пример кода:

var merge = require('merge'), // npm install -g merge
    original, cloned;

console.log(

    merge({ one: 'hello' }, { two: 'world' })

); // {"one": "hello", "two": "world"}

original = { x: { y: 1 } };

cloned = merge(true, original);

cloned.x.y++;

console.log(original.x.y, cloned.x.y); // 1, 2

Ответ 6

Я вижу, что этот поток слишком старый, но я поставил свой ответ здесь только в целях ведения журнала.

В одном из комментариев выше вы упомянули, что хотите использовать "экспресс" в вашем проекте, который имеет библиотеку "connect" в список зависимостей. На самом деле библиотека 'connect.utils' содержит 'merge' метод, который делает трюк. Таким образом, вы можете использовать стороннюю сторону без добавления каких-либо новых сторонних библиотек.

Ответ 7

Вот простое решение, чтобы объединить JSON. Я сделал следующее.

  • Преобразуйте каждый из JSON в строки с помощью JSON.stringify(object).
  • Объединить все строки JSON с помощью оператора +.
  • Замените шаблон /}{/g на ","
  • Разберите строку результатов обратно к объекту JSON

    var object1 = {name: "John"};
    var object2 = {location: "San Jose"};
    var merged_object = JSON.parse((JSON.stringify(object1) + JSON.stringify(object2)).replace(/}{/g,","))
    

Итоговый объединенный JSON будет

{name: "John", location: "San Jose"}

Ответ 8

Вы также можете использовать этот легкий пакет npm под названием absorb

Это 27 строк кода, 1kb и использует рекурсию для выполнения глубоких слияний объектов.

var absorb = require('absorb');
var obj1, obj2;

obj1 = { foo: 123, bar: 456 };
obj2 = { bar: 123, key: 'value' }

absorb(obj1, obj2);

console.log(obj1); // Output: { foo: 123, bar: 123, key: 'value' }

Вы также можете использовать его для создания клона или передачи только значений, если они не существуют в исходном объекте, как это сделать подробно описано в предоставленной ссылке.

Ответ 9

Если вам нужны специальные поведения, такие как вложенное расширение объекта или замена массива, вы можете использовать Node.js extendify.

var extendify = require('extendify');

_.extend = extendify({
    inPlace: false,
    arrays : 'replace',
    isDeep: true
});

obj1 = {
    a:{
        arr: [1,2]
    },
    b: 4
};

obj2 = {
    a:{
        arr: [3]
    }
};

res = _.extend(obj1,obj2);
console.log(JSON.stringify(res)); //{'a':{'arr':[3]},'b':4}

Ответ 10

Lodash - еще одна мощная опция инструментального ремня для этих видов утилит. Смотрите: _.merge() (который является рекурсивным)

var object = {
  'a': [{ 'b': 2 }, { 'd': 4 }]
};
var other = {
  'a': [{ 'c': 3 }, { 'e': 5 }]
}; 
_.merge(object, other);
// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } 

Ответ 11

Это легко сделать с помощью метода Object.assign() -

 var object1 = {name: "John"};
 var object2 = {location: "San Jose"};
 var object3 = Object.assign(object1,object2);
 console.log(object3);

now object3 is {name: 'John', location: 'San Jose'}

Ответ 12

Следующий код поможет вам объединить два объекта JSON с вложенными объектами.

function mergeJSON(source1,source2){
    /*
     * Properties from the Souce1 object will be copied to Source2 Object.
     * Note: This method will return a new merged object, Source1 and Source2 original values will not be replaced.
     * */
    var mergedJSON = Object.create(source2);// Copying Source2 to a new Object

    for (var attrname in source1) {
        if(mergedJSON.hasOwnProperty(attrname)) {
          if ( source1[attrname]!=null && source1[attrname].constructor==Object ) {
              /*
               * Recursive call if the property is an object,
               * Iterate the object and set all properties of the inner object.
              */
              mergedJSON[attrname] = zrd3.utils.mergeJSON(source1[attrname], mergedJSON[attrname]);
          } 

        } else {//else copy the property from source1
            mergedJSON[attrname] = source1[attrname];

        }
      }

      return mergedJSON;
}

Ответ 13

Вы можете использовать Lodash

const _ = require('lodash');

let firstObject = {'email' : '[email protected]};
let secondObject = { 'name' : { 'first':message.firstName } };
_.merge(firstObject, secondObject)

Ответ 14

Лучший подход от правильного решения здесь, чтобы не изменять цель:

function extend(){
  let sources = [].slice.call(arguments, 0), result = {};
  sources.forEach(function (source) {
    for (let prop in source) {
      result[prop] = source[prop];
    }
  });
  return result;
}

Ответ 15

Пусть object1 и object2 - два объекта JSON.

var object1 = [{"name": "John"}];
var object2 = [{"location": "San Jose"}];

object1.push(object2);

Это просто добавит object2 в object1:

[{"name":"John"},{"location":"San Jose"}]