Объединить объект с массивами - PullRequest
0 голосов
/ 25 октября 2019

Я хотел бы объединить объекты с массивами, но, похоже, он не работает должным образом.

Я хотел бы объединить массивы, но сохранить уникальные элементы по метке.

Первый объект:

var object1 = {
  index: [
    {
      label: 'Ajouter',
      url: '/_add/:model',
      icon: 'add',
      isMain: true
    },
    {
      label: 'Exporter en CSV',
      url: '/_export/:model',
      icon: 'cloud_download'
    },
    {
      label: 'Accès à l\'API',
      url: '/api/_index/:model',
      target: '_blank',
      icon: 'link'
    }
  ],
  add: [
    {
      label: 'Retour',
      url: '/_index/:model',
      icon: 'arrow_back'
    }
  ],
  edit: [
    {
      label: 'Retour',
      icon: 'arrow_back',
      url: '/_index/:model'
    },
    {
      label: 'Supprimer',
      icon: 'delete',
      url: '/_delete/:model/:id'
    }
  ]
};

Второй объект:

var object2 = _.mergeWith(_.clone(object1), {
  index: [
    {
      label: 'Explorateur ',
      url: '/file/_folder-explorer/uploads',
      target: '_blank',
      icon: 'folder_open'
    },
    {
      label: 'Ajout multiple ',
      url: '/file/_add-multiple',
      icon: 'library_add'
    }
  ],
  edit: [
    {
      label: 'Retour',
      icon: 'arrow_back',
      url: '/file/_index'
    }
  ]
}, customizerMergeActions);

function customizerMergeActions(objValue, srcValue) {
  if (_.isArray(objValue)) {
    return objValue.concat(srcValue);
  }
}

Проблема: В ключе "edit" я получилтот же объект "label: 'Retour'", я хотел бы сохранить последний ...

Ответы [ 2 ]

0 голосов
/ 25 октября 2019

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

const fn = (key, ...objs) => _.mergeWith({}, ...objs, (v1, v2) => {
  if(!_.isArray(v1)) return;
  
  /** convert both arrays to objects indexed by the chosen key, 
      merge them using the fn (this will handle arrays inside arrays)
      and then convert back to array with _.values() **/
  return _.values(fn(key, _.keyBy(v1, key), _.keyBy(v2, key)));
});

const object1 = {"index":[{"label":"Ajouter","url":"/_add/:model","icon":"add","isMain":true},{"label":"Exporter en CSV","url":"/_export/:model","icon":"cloud_download"},{"label":"Accès à l'API","url":"/api/_index/:model","target":"_blank","icon":"link"}],"add":[{"label":"Retour","url":"/_index/:model","icon":"arrow_back"}],"edit":[{"label":"Retour","icon":"arrow_back","url":"/_index/:model"},{"label":"Supprimer","icon":"delete","url":"/_delete/:model/:id"}]};

const object2 = {"index":[{"label":"Explorateur ","url":"/file/_folder-explorer/uploads","target":"_blank","icon":"folder_open"},{"label":"Ajout multiple ","url":"/file/_add-multiple","icon":"library_add"}],"edit":[{"label":"Retour","icon":"arrow_back","url":"/file/_index"}]};

const result = fn('label', object1, object2);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Версия ES5:

function fn(key, arr1, arr2) {
  return _.mergeWith({}, arr1, arr2, function(v1, v2) {
    if(!_.isArray(v1)) return;

    /** convert both arrays to objects indexed by the chosen key, 
        merge them using the fn (this will handle arrays inside arrays)
        and then convert back to array with _.values() **/
    return _.values(fn(key, _.keyBy(v1, key), _.keyBy(v2, key)));
  });
}

var object1 = {"index":[{"label":"Ajouter","url":"/_add/:model","icon":"add","isMain":true},{"label":"Exporter en CSV","url":"/_export/:model","icon":"cloud_download"},{"label":"Accès à l'API","url":"/api/_index/:model","target":"_blank","icon":"link"}],"add":[{"label":"Retour","url":"/_index/:model","icon":"arrow_back"}],"edit":[{"label":"Retour","icon":"arrow_back","url":"/_index/:model"},{"label":"Supprimer","icon":"delete","url":"/_delete/:model/:id"}]};

var object2 = {"index":[{"label":"Explorateur ","url":"/file/_folder-explorer/uploads","target":"_blank","icon":"folder_open"},{"label":"Ajout multiple ","url":"/file/_add-multiple","icon":"library_add"}],"edit":[{"label":"Retour","icon":"arrow_back","url":"/file/_index"}]};

var result = fn('label', object1, object2);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
0 голосов
/ 25 октября 2019

Если я правильно понял ваш вопрос, вы хотите перезаписать значения из объекта source , т.е. (второй параметр функции mergeWith), с соответствующими значениями в переменной object1 . Таким образом, вместо использования функции concat в функции customizerMergeActions используйте это,

function customizerMergeActions(objValue, srcValue) {
    if (_.isArray(objValue)) {
        return _.merge(objValue, srcValue);
    }
}

Таким образом, ключ редактирования теперь будет содержать этот массив объектов,

[
    {label: "Retour", icon: "arrow_back", url: "/file/_index"},
    {label: "Supprimer", icon: "arrow_back", url: "/_delete/:model/:id"}
]
...