2015-08-26 3 views
0

Желательно объединить два объекта. Однако, когда свойство «дата» с одинаковым значением существует в обоих объектах, другие свойства (tag1 и tag2) должны быть забиты под одну и ту же дату.Объединение объектов javascript

Пример ввода

var myVar1 = [ 
{ 
"date": "2015-07-16", 
    "tag1": 35.34}, 
{ 
"date": "2015-07-18", 
    "tag1": 34.12} 
    ]; 

var myVar2 = [ 
{ 
"date": "2015-07-16", 
    "tag2": 45.34}, 
{ 
"date": "2015-07-17", 
    "tag2": 44.12} 
    ]; 

Желаемая выход

mergedVar = [ 
{ 
"date": "2015-07-16", 
    "tag1": 35.34, 
    "tag2": 45.34}, 
{ 
"date": "2015-07-17", 
    "tag2": 44.12}, 
{ 
"date": "2015-07-18", 
    "tag1": 34.12} 
    ]; 
+0

Не пользуйтесь этой реализацией, но мне было весело [golfing] (https://en.wikipedia.org/wiki/Code_golf): 'function merge (G, o, l, f, i , п, г, I, s, F, U, N) {и = {}, N = []; при (о = 0, L = G.length; о <л; о ++) для (F = 0, я = (п = о [о]) длина; е. <я, е ++) {г = п [е]; I = (U [F = '#' + g.date] || (N.push (я = {}), u [F] = I)), для (s в g) Object.prototype.hasOwnProperty.call (g, s) && (I [s] = g [s])} return N} 'Использование : 'var mergedVar = merge ([myVar1, myVar2]);' – icktoofay

+0

@icktoofay ok. Я не буду (читать не могу) использовать реализацию. Я новичок в JavaScript и не могу использовать здесь небольшую помощь. Вопрос в том, какова правильная реализация? Благодарю. – luvlogic

ответ

2

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

Прежде всего, вам нужно знать, как объединить один объект в другой. Это не так уж сложно, но вы должны знать, как использовать for - in, который не часто преподается, и это, как правило, хорошая идея, чтобы включать в себя hasOwnProperty чек, который даже менее часто преподается:

function mergeObjectInto(source, target) { 
    for(var property in source) { 
     if(Object.prototype.hasOwnProperty.call(source, property)) { 
      target[property] = source[property]; 
     } 
    } 
} 

По существу, это перечисляет все свойства источника. Если это свойство является собственностью объекта объекта, то есть это не то, что унаследовано от его прототипа - мы копируем это свойство в цель.

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

function mergeObjectIntoArray(existingArray, newObject) { 
    // Search for an already-existing object in the array that shares the same 
    // value for the `date' property. 
    var correspondingExistingObject = null; 
    for(var index = 0, length = existingArray.length; index < length; index++) { 
     if(existingArray[index].date === newObject.date) { 
      correspondingExistingObject = existingArray[index]; 
      break; 
     } 
    } 
    if(correspondingExistingObject !== null) { 
     // If we found an existing object that corresponds to our new object, just 
     // merge any new properties in rather than adding a new item to the array. 
     mergeObjectInto(newObject, correspondingExistingObject); 
    }else{ 
     // Otherwise, bite the bullet and add the new object since there's nothing 
     // we can usefully merge into. 
     existingArray.push(newObject); 
    } 
} 

Вы могли бы реализовать вид операции слияния вы хотели, вызвав эту функцию в цикле. Но если вы это сделаете, это будет иметь квадратичное время, что будет проблемой, если это должно работать с большим количеством элементов данных. Как это бывает, есть способ, которым вы можете обойти это. Если мы сортируем элементы в структуру, похожую на хэш-таблицу, связанную с свойством date по мере того, как мы идем, мы можем проверить постоянное время, есть ли у нас объект с этой датой или нет, и если это так, слейте в него; в противном случае добавьте его. Это приводит к очень разумному линейному времени для всего алгоритма.

Одним из осложнений является то, что до недавнего времени с ECMAScript 6 у JavaScript действительно не было реальной «хэш-таблицы». Самое близкое, что у нас есть, это объекты, которые могут иметь только строковые ключи. Это сработает для нас, но нам нужно проявлять некоторую осторожность: к лучшему или худшему, разработчики браузеров создали некоторые имена свойств с особым значением, например __proto__, что мы действительно не хотим наступать, поэтому мы будем префикс наших ключей с некоторым символом, который предотвращает любые столкновения со встроенными именами. Для этой цели я выбрал #. (# хэш, и это хэш-таблица.)

В коде, вот как это будет работать, на этот раз функции принимает весь массив элементов и объединение всех объектов с одинаковыми значениями date собственности:

function mergeDuplicateObjectsInArray(array) { 
    var result = []; 
    var objectsByDate = {}; 
    for(var index = 0, length = array.length; index < length; index++) { 
     var object = array[index]; 
     var hashKey = '#' + object.date; 
     var mergeTarget; 
     if(Object.prototype.hasOwnProperty.call(objectsByDate, hashKey)) { 
      // Already have an object by that date; we ought to merge into that. 
      mergeObjectInto(object, objectsByDate[object.date]); 
     }else{ 
      // No object by that date yet; we'll be the first. 
      result.push(object); 
      objectsByDate[object.date] = object; 
     } 
    } 
    return result; 
} 

Это все еще пропустит последнее: оно объединяет объекты только в одном массиве, а не в двух разных массивах. Но он будет делать то, что вам нужно, если вы создали один массив с объектами обоих массивов, например. myVar1.concat(myVar2). В любом случае вы также можете изменить цикл for в нем, чтобы перебрать массив массивов, а затем перебрать объекты в этих массивах, что и сделала моя версия для гольфа.Другое отличие от версии для игры в гольф - это игра в гольф, позволяющая модифицировать оригинальные массивы или объекты, что было бы относительно простой модификацией несвязанной версии: сделать копию просто слить в пустой объект.

Надеюсь, это прояснит ситуацию.

Смежные вопросы