对象数组,用于累积另一个 属性 相同的所有对象属性

Array of objects to accumulate all object properties for which another property is the same

假设我的对象数组如下所示:

array1 = [
    { 
         rule: {
             column: "colName",
             value: "val1"
         }
    },
    { 
         rule: {
             column: "colName",
             value: "val2"
         }
    },
    { 
         rule: {
             column: "colName",
             value: "val3"
         }
    },
    { 
         rule: {
             column: "colName2",
             value: "val4"
         }
    }
]

我想写一些类似 reduce 的操作来检查 rule.column 是否对所有数组元素都相等,如果是,则推入其中一个的值,同时删除其他元素。 给我这样的东西:

array2 = [
    { 
         rule: {
             column: "colName",
             value: ["val1", "val2", "val3"]
         }
    },
    { 
         rule: {
             column: "colName2",
             value: ["val4"]
         }
    }
]

有没有直接的方法来做到这一点? 我绝对可以写一个常规的 function 来做到这一点,但我假设我应该能够对 array1 进行 reduce 操作?

编辑:原问题在rule之后有otherProperty: {}属性,但我的对象实际上没有那个(它在上层对象上)

当然,只需创建一个对象,其键与每一列匹配,推送到内部 values 数组,然后获取对象的值:

const input = [{
    rule: {
      column: "colName",
      value: 'v1'
    },
    otherProperty: 'otherProp',
  },
  {
    rule: {
      column: "colName",
      value: 'v2'
    },
    otherProperty: 'otherProp',
  },
  {
    rule: {
      column: "colName",
      value: 'val3',
    },
    otherProperty: 'otherProp',
  },
  {
    rule: {
      column: "colName2",
      value: 'val4'
    },
    otherProperty: 'otherProp',
  }
];
const outputCols = input.reduce((outputCols, { rule: { column, value }, ...otherProps}) => {
  if (!outputCols[column]) {
    outputCols[column] = { rule: { column, value: [] }, ...otherProps };
  }
  outputCols[column].rule.value.push(value);
  return outputCols;
}, {});
console.log(Object.values(outputCols));

请注意,如果 otherProps 在后续对象中不同,则当前将忽略它们。

您可以使用函数reduce进行分组,然后将值作为数组获取。

名称 otherProperty 超出范围,但您可以使用函数 Object.assign 或 Spread 语法。

let array1 = [    {          rule: {             column: "colName",             value: ["val1"]         },         otherProperty: {}    },    {          rule: {             column: "colName",             value: ["val2"]         },         otherProperty: {}    },    {          rule: {             column: "colName",             value: ["val3"]         },         otherProperty: {}    },    {          rule: {             column: "colName2",             value: ["val4"]         },         otherProperty: {}    }],
    result = Object.values(array1.reduce((a, c) => {
      (a[c.rule.column] || (a[c.rule.column] = {rule: {column: c.rule.column, value: []}, otherProperty: {}})).rule.value.push(...c.rule.value);
      return a;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }