繁体   English   中英

如何根据多个键从 object 数组中返回一个数组

[英]How to return a array from array of object based on multiple keys

我有一个具有多个值的 object 数组,但我必须根据键将值过滤到数组中,并将值合并到具有相同值的数组中。 我尝试了不同的步骤,可以在单个映射/过滤/减少中完成吗?

const a = [
    {abc: ['add', 'edit'], cond: []},
    {cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: []},
    {cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work']},
];
const expected result = {
    cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'],  matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx', 'delete_matx'], work: ['add_work', 'edit_work','view_work', 'delete_work']
}

const b = a.map(el => el.cond);

const c = a.map(el => el.matx);

const d = a.map(el => el.work);

result = {cond: [...b], matx: [...c], work: [...d]}

您可以将所有想要的属性值收集到一个集合中,并从键/值对构建一个新的 object。

 const data = [{ abc: ['add', 'edit'], cond: [] }, { cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: [] }, { cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work'] }], keys = ['cond', 'matx', 'work'], addToSet = (s, v) => s.add(v), result = Object.fromEntries(keys.map(k => [ k, [...data.reduce((r, o) => (o[k] || []).reduce(addToSet, r), new Set)] ])); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

它不能用 forEach 完成... .map() .reduce( .reduce().filter()将始终返回一个数组而不是 object。

 const a = [ {abc: ['add', 'edit'], cond: []}, {cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: []}, {cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work']}, ]; const result = {cond: [], work: [], matx: []} a.forEach(x=> { x.cond && result.cond.push(...x.cond); x.work && result.work.push(...x.work); x.matx && result.work.push(...x.matx); } ); console.log(result);

const a = [
  { abc: ["add", "edit"], cond: [] },
  {
    cond: ["add_cond", "edit_cond", "view_cond"],
    matx: ["add_matx", "edit_matx", "delete_matx"],
    work: ["add_work", "edit_work"],
    def: [],
  },
  {
    cond: ["add_cond", "edit_cond", "view_cond", "delete_cond"],
    matx: ["add_matx", "edit_matx", "view_matx", "store_matx"],
    work: ["view_work", "delete_work"],
  },
];

function mapper(a) {
  let result = {};
  for (let i = 0; i < a.length - 1; i++) {
    result = Object.assign(a[i], a[i + 1]);
  }
  return result;
}

console.log(mapper(a));

结果--->

{
  cond: [ 'add_cond', 'edit_cond', 'view_cond', 'delete_cond' ],
  matx: [ 'add_matx', 'edit_matx', 'view_matx', 'store_matx' ],
  work: [ 'view_work', 'delete_work' ],
  def: []
}

您可以使用单个reduce方法来实现此目的。 所有键都是动态评估的,因此无论您向对象添加/删除多少键,您都会获得动态添加的键:

 const a = [ {abc: ['add', 'edit'], cond: []}, {cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: []}, {cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work']}, ]; const result = a.reduce((prev, cur) => { const keys = Object.keys(cur); keys.forEach(el => { if(prev[el] === undefined) prev[el] = [] prev[el].push(cur[el]) prev[el] = prev[el].flat() }) return prev }, {}) console.log(result)

因此,基于您只想要 arrays 您只会错过.forEach进行迭代并且这里的大多数 forEach-anwers 都是错误的,您可以通过每个循环 go 并分解问题:

 const a = [ {abc: ['add', 'edit'], cond: []}, {cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: []}, {cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work']}, ]; const result = {cond: [], matx: [], work: []} a.forEach( current_dict => { Object.entries(current_dict).filter(current_entry => current_entry[0] in result).forEach( current_entry => { current_entry[1].filter(value =>.result[current_entry[0]].includes(value)).forEach( value => { result[current_entry[0]].push(value) } ) } ) } ) console.log(result)

请注意,未订购 arrays。 如果您需要订单,您应该使用字典而不是 arrays 或映射 function 类型,例如condOrderFunction(option){/*something*/return index}

我不确定为什么它与预期的结果不同,但试试这个:

 const a = [ {abc: ['add', 'edit'], cond: []}, {cond: ['add_cond', 'edit_cond', 'view_cond'], matx: ['add_matx', 'edit_matx', 'delete_matx'], work: ['add_work', 'edit_work'], def: []}, {cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx'], work: ['view_work', 'delete_work']}, ]; const expectedResult = { cond: ['add_cond', 'edit_cond', 'view_cond', 'delete_cond'], matx: ['add_matx', 'edit_matx', 'view_matx', 'store_matx', 'delete_matx'], work: ['add_work', 'edit_work','view_work', 'delete_work'] } const result = a.reduce( (prev, curr) => ({ cond: [...new Set([...prev.cond, ...curr.cond || []])], matx: [...new Set([...prev.matx, ...curr.matx || []])], work: [...new Set([...prev.work, ...curr.work || []])], }), { cond: [], matx: [], work: [] } ); console.log("Expected cond: ", expectedResult.cond); console.log("Actual cond: ", result.cond); console.log("Expected matx: ", expectedResult.matx); console.log("Actual matx: ", result.cond); console.log("Expected work: ", expectedResult.work); console.log("Actual work: ", result.cond);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM