按键/值合并对象数组

时间:2017-08-14 21:30:51

标签: javascript arrays

如果特定键值匹配,我需要合并两个单独的对象数组。分析数据后可能会更有意义:

数组1

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  foo computed property sum: {{ sum }}
  <Foo v-for="index in 10" v-model="foos[index]"></Foo>
</div>

数组2

let categories = [
    { id: 5, slug: 'category-5', items: []  },
    { id: 4, slug: 'category-4', items: []  },
    { id: 3, slug: 'category-3', items: []  },
]

预期输出

let items = [
    { id: 5, data: [{ title: 'item title', description: 'item description' }] },
    { id: 5, data: [{ title: 'item title 2', description: 'item description 2' }] },
    { id: 4, data: [{ title: 'item title 4', description: 'item description 4' }] },
]

所以......如果他们的id匹配,我需要将数组2 添加到数组1 数组1 将保持不变,但如果数组2 匹配,数组1的属性(空)将被 Array 2

的data属性替换

我知道这是一个非常基本/冗余的问题,但我找不到我的用例/对象结构的资源。

我能够轻松地使用lodash对数组进行分组 - 所以如果有一个与该库类似的解决方案 - 那就太好了!或者只是某个方向就足够了。

提前致谢!

3 个答案:

答案 0 :(得分:1)

您可以循环第一个数组,然后使用import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; //<-- FormsModule import import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule, FormsModule ], //<-- added FormsModule to imports option declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { } 获取与当前元素具有相同ID的对象,并将该项添加到当前对象。

filter

答案 1 :(得分:0)

我会将类别设为哈希映射,键将是id并仅迭代所有项目。 然后你得到O(N)解决方案。

答案 2 :(得分:0)

您可以将项目分类:

let res = items.reduce((a, b) => {
  let it = a.find(e => e.id === b.id);
  if (! it) return a;
  it.items = it.items.concat(b.data);
  return a;
}, categories);

let categories = [{
    id: 5,
    slug: 'category-5',
    items: []
  },
  {
    id: 4,
    slug: 'category-4',
    items: []
  },
  {
    id: 3,
    slug: 'category-3',
    items: []
  },
];

let items = [{
    id: 5,
    data: [{
      title: 'item title',
      description: 'item description'
    }]
  },
  {
    id: 5,
    data: [{
      title: 'item title 2',
      description: 'item description 2'
    }]
  },
  {
    id: 4,
    data: [{
      title: 'item title 4',
      description: 'item description 4'
    }]
  },
];

let res = items.reduce((a, b) => {
  let it = a.find(e => e.id === b.id);
  if (! it) return a;
  it.items = it.items.concat(b.data);
  return a;
}, categories);

console.log(res);

首先在对象中获取id可能会更快,因此我们不必多次对同一个id使用find

function merge(result, toMerge, mergeInto) {
    let i = 0, hm = {};
    for (let {id} of categories) {
        hm[id] = i;
        i++;
    }
    return toMerge.reduce((a,b) => {
        let it = a[hm[b.id]];
        if (!it) return a;
        it[mergeInto] = it[mergeInto].concat(b.data);
        return a;
    }, result);
}

let categories = [
    { id: 5, slug: 'category-5', items: []  },
    { id: 4, slug: 'category-4', items: []  },
    { id: 3, slug: 'category-3', items: []  },
];

let items = [
    { id: 5, data: [{ title: 'item title', description: 'item description' }] },
    { id: 5, data: [{ title: 'item title 2', description: 'item description 2' }] },
    { id: 4, data: [{ title: 'item title 4', description: 'item description 4' }] },
];

function merge(result, toMerge, mergeInto) {
    let i = 0, hm = {};
    for (let {id} of categories) {
        hm[id] = i;
        i++;
    }
    return toMerge.reduce((a,b) => {
        let it = result[hm[b.id]];
        if (!it) return a;
        it[mergeInto] = it[mergeInto].concat(b.data);
        return a;
    }, result);
}


console.log(merge(categories, items, 'items'));