Как объединить объекты в массиве с конкатенацией массивов свойств?

Требуется объединить объекты в массиве с одинаковыми значениями date, и чтобы массивы свойств конкатенировались, а не оверврайтились.

То есть, если мы соединяем array[0] и array[1], т.к их значения date идентичны, то элементы массивов array[0].schedule и array[1].schedule складывались, аналогично и с array[0]._data.teachers и subjs.

const array = [
  {
    date: '22.09',
    schedule: [
      { 
        key2: '3123123dadkaksjd',
        key: [
          {a: 0, b: 2, text: 'dasd'},
          {a: 4, b:4, text: 'dasdsad'}
        ]
      },
      { 
        key2: 'asdaosdio',
        key: [
          {a: 0, b: 2, text: 'dasd'},
          {a: 4, b:4, text: 'dasdsad'}
        ]
      }
    ],
    _data: {
      teachers: [{name: 'dasd', cab: 224}, {name: 'oaoaoa', cab: 444}],
      subjs: [{name: 'Math', a: 1, b: 2}, {name: 'Computer Science', a: 4, b: 6}]
    }
  },
  {
    date: '22.09',
    schedule: [
      { 
        key2: 'darpoqoe',
        key: [
          {a: 8, b: 2, text: 'dasdasd'},
          {a: 4, b:0, text: 'zcxzxczxc'}
        ]
      },
      { 
        key2: 'cmz.x,m,xzc',
        key: [
          {a: 323, b: 97, text: 'cmzkxcmzx.c'},
          {a: 41, b:33, text: 'zxcmzxm,cn'}
        ]
      }
    ],
    _data: {
      teachers: [{name: 'Daposdpods', cab: 2242}, {name: 'ADnmx', cab: 4414}],
      subjs: [{name: 'Lang', a: 1, b: 2}, {name: 'XZxxz', a: 4, b: 6}]
    }
  },
  {
    date: '23.09',
    schedule: [
      { 
        key2: 'aspdpasdop',
        key: [
          {a: 8, b: 2, text: 'zxczxczxc'},
          {a: 4, b:0, text: 'zcxzxczxc'}
        ]
      },
      { 
        key2: '123123124',
        key: [
          {a: 323, b: 97, text: '4123213fxzc.c'},
          {a: 41, b:33, text: 'zxcmz123123ncmzxm,cn'}
        ]
      }
    ],
    _data: {
      teachers: [{name: 'Daposzxczxcdpods', cab: 2242}, {name: 'AvzxcDnmx', cab: 4414}],
      subjs: [{name: 'Lanvzxg', a: 1, b: 2}, {name: 'XZxxz', a: 4, b: 6}]
    }
  }
]
  • Вопрос задан
  • 105 просмотров
Решения вопроса 1
@sugarbaby Автор вопроса
Решил таким способом:

import isWhat, {isPlainObject, isSymbol, isArray} from 'is-what'

const array = [
  {
    date: '22.09',
    schedule: [
      { 
        key2: '3123123dadkaksjd',
        key: [
          {a: 0, b: 2, text: 'dasd'},
          {a: 4, b:4, text: 'dasdsad'}
        ]
      },
      { 
        key2: 'asdaosdio',
        key: [
          {a: 0, b: 2, text: 'dasd'},
          {a: 4, b:4, text: 'dasdsad'}
        ]
      }
    ],
    _data: {
      teachers: [{name: 'dasd', cab: 224}, {name: 'oaoaoa', cab: 444}],
      subjs: [{name: 'Math', a: 1, b: 2}, {name: 'Computer Science', a: 4, b: 6}]
    }
  },
  {
    date: '22.09',
    schedule: [
      { 
        key2: 'darpoqoe',
        key: [
          {a: 8, b: 2, text: 'dasdasd'},
          {a: 4, b:0, text: 'zcxzxczxc'}
        ]
      },
      { 
        key2: 'cmz.x,m,xzc',
        key: [
          {a: 323, b: 97, text: 'cmzkxcmzx.c'},
          {a: 41, b:33, text: 'zxcmzxm,cn'}
        ]
      }
    ],
    _data: {
      teachers: [{name: 'Daposdpods', cab: 2242}, {name: 'ADnmx', cab: 4414}],
      subjs: [{name: 'Lang', a: 1, b: 2}, {name: 'XZxxz', a: 4, b: 6}]
    }
  },
  {
    date: '23.09',
    schedule: [
      { 
        key2: 'aspdpasdop',
        key: [
          {a: 8, b: 2, text: 'zxczxczxc'},
          {a: 4, b:0, text: 'zcxzxczxc'}
        ]
      },
      { 
        key2: '123123124',
        key: [
          {a: 323, b: 97, text: '4123213fxzc.c'},
          {a: 41, b:33, text: 'zxcmz123123ncmzxm,cn'}
        ]
      }
    ],
    _data: {
      teachers: [{name: 'Daposzxczxcdpods', cab: 2242}, {name: 'AvzxcDnmx', cab: 4414}],
      subjs: [{name: 'Lanvzxg', a: 1, b: 2}, {name: 'XZxxz', a: 4, b: 6}]
    }
  }
]

function assignProp(carry, key, newVal, originalObject) {
    var propType = {}.propertyIsEnumerable.call(originalObject, key)
        ? 'enumerable'
        : 'nonenumerable';
    if (propType === 'enumerable')
        carry[key] = newVal;
    if (propType === 'nonenumerable') {
        Object.defineProperty(carry, key, {
            value: newVal,
            enumerable: false,
            writable: true,
            configurable: true,
        });
    }
}

function __spreadArrays() {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
}

function concatArrays(originVal, newVal) {
    if (isArray(originVal) && isArray(newVal)) {
        // concat logic
        return originVal.concat(newVal);
    }
    return newVal; // always return newVal as fallback!!
}

function mergeRecursively(origin, newComer, compareFn) {
    // always return newComer if its not an object
    if (!isPlainObject(newComer))
        return newComer;
    // define newObject to merge all values upon
    var newObject = {};
    if (isPlainObject(origin)) {
        var props_1 = Object.getOwnPropertyNames(origin);
        var symbols_1 = Object.getOwnPropertySymbols(origin);
        newObject = __spreadArrays(props_1, symbols_1).reduce(function (carry, key) {
            var targetVal = origin[key];
            if ((!isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) ||
                (isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))) {
                assignProp(carry, key, targetVal, origin);
            }
            return carry;
        }, {});
    }
    // newObject has all properties that newComer hasn't
    var props = Object.getOwnPropertyNames(newComer);
    var symbols = Object.getOwnPropertySymbols(newComer);
    var result = __spreadArrays(props, symbols).reduce(function (carry, key) {
        // re-define the origin and newComer as targetVal and newVal
        var newVal = newComer[key];
        var targetVal = isPlainObject(origin) ? origin[key] : undefined;
        // When newVal is an object do the merge recursively
        if (targetVal !== undefined && isPlainObject(newVal)) {
            newVal = mergeRecursively(targetVal, newVal, compareFn);
        }
        var propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal;
        assignProp(carry, key, propToAssign, newComer);
        return carry;
    }, newObject);
    return result;
}

function mergeAndConcat(object) {
    var otherObjects = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        otherObjects[_i - 1] = arguments[_i];
    }
    // @ts-ignore
    return otherObjects.reduce(function (result, newComer) {
        return mergeRecursively(result, newComer, concatArrays);
    }, object);
}




const getUnqiueKeyValues = (array, key) => {
    const result = []
    array.forEach((v) => {
        const keyValue = v[key]

        if (!result.some((obj) => obj === keyValue)) {
        result.push(keyValue)
        }
    })

    return result
}

const mergeNotUniqueObjectsByKey = (array, key) => {
    const uniqueKeyValues = getUnqiueKeyValues(array, key)

    const resultArray = []

    uniqueKeyValues.forEach((date) => {
        const matches = array.filter((_) => _.date === date)
        const merged = mergeAndConcat(...matches)

        resultArray.push(merged)
    })

    return resultArray
}

mergeNotUniqueObjectsByKey(array, 'date')


Результат:

[
  {
    date: '22.09',
    schedule: [
      {
        key2: '3123123dadkaksjd',
        key: [
          { a: 0, b: 2, text: 'dasd' },
          { a: 4, b: 4, text: 'dasdsad' }
        ]
      },
      {
        key2: 'asdaosdio',
        key: [
          { a: 0, b: 2, text: 'dasd' },
          { a: 4, b: 4, text: 'dasdsad' }
        ]
      },
      {
        key2: 'darpoqoe',
        key: [
          { a: 8, b: 2, text: 'dasdasd' },
          { a: 4, b: 0, text: 'zcxzxczxc' }
        ]
      },
      {
        key2: 'cmz.x,m,xzc',
        key: [
          { a: 323, b: 97, text: 'cmzkxcmzx.c' },
          { a: 41, b: 33, text: 'zxcmzxm,cn' }
        ]
      }
    ],
    _data: {
      teachers: [
        { name: 'dasd', cab: 224 },
        { name: 'oaoaoa', cab: 444 },
        { name: 'Daposdpods', cab: 2242 },
        { name: 'ADnmx', cab: 4414 }
      ],
      subjs: [
        { name: 'Math', a: 1, b: 2 },
        { name: 'Computer Science', a: 4, b: 6 },
        { name: 'Lang', a: 1, b: 2 },
        { name: 'XZxxz', a: 4, b: 6 }
      ]
    }
  },
  {
    date: '23.09',
    schedule: [
      {
        key2: 'aspdpasdop',
        key: [
          { a: 8, b: 2, text: 'zxczxczxc' },
          { a: 4, b: 0, text: 'zcxzxczxc' }
        ]
      },
      {
        key2: '123123124',
        key: [
          { a: 323, b: 97, text: '4123213fxzc.c' },
          { a: 41, b: 33, text: 'zxcmz123123ncmzxm,cn' }
        ]
      }
    ],
    _data: {
      teachers: [
        { name: 'Daposzxczxcdpods', cab: 2242 },
        { name: 'AvzxcDnmx', cab: 4414 }
      ],
      subjs: [
        { name: 'Lanvzxg', a: 1, b: 2 },
        { name: 'XZxxz', a: 4, b: 6 }
      ]
    }
  }
]
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@kikkigenkai
Может я что-то неправильно понял, но вроде работает

function concat(arr1, arr2) {
  let obj = [];

  if (arr1.date === arr2.date) {
    obj = JSON.parse(JSON.stringify(arr1));

    Object.assign(obj[0].data, JSON.parse(JSON.stringify(arr1[0].data)), JSON.parse(JSON.stringify(arr2[0].data)));

    return obj;
  }
}
Ответ написан
@ArturFirst
Если подгонять под данную структуру...
Object.values(array.reduce((acc, item, i) => {
  const { date, schedule, _data } = item;
  const { teachers, subjs } = _data;
  if (!acc.hasOwnProperty(date)) acc[date] = item 
  else {
    acc[date].schedule = [ ...acc[date].schedule, ...schedule];
    acc[date]._data.teachers = [...acc[date]._data.teachers, ...teachers];
    acc[date]._data.subjs = [...acc[date]._data.subjs, ...subjs];
  }
  return acc;
}, {}))
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы