Я отправил свой комментарий с идеей, что кто-то вывесил бы более серьезный ответ, но так как никто не приходил, я предполагаю, что я буду расскажите, как вы можете серьезно относиться к этому.
Прежде всего, вам нужно знать, как объединить один объект в другой. Это не так уж сложно, но вы должны знать, как использовать 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
в нем, чтобы перебрать массив массивов, а затем перебрать объекты в этих массивах, что и сделала моя версия для гольфа.Другое отличие от версии для игры в гольф - это игра в гольф, позволяющая модифицировать оригинальные массивы или объекты, что было бы относительно простой модификацией несвязанной версии: сделать копию просто слить в пустой объект.
Надеюсь, это прояснит ситуацию.
Не пользуйтесь этой реализацией, но мне было весело [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
@icktoofay ok. Я не буду (читать не могу) использовать реализацию. Я новичок в JavaScript и не могу использовать здесь небольшую помощь. Вопрос в том, какова правильная реализация? Благодарю. – luvlogic