Javascript中优雅的数组转换

时间:2017-02-12 18:38:03

标签: javascript ecmascript-6

什么是一种优雅的方式 - 纯粹功能性,理想情况下 - 转换(减少?)这个数组:

var in = [
  { a: 1, b: 'x', c: 'foo' },
  { a: 1, b: 'y', c: 'goo' },
  { a: 2, b: 'x', c: 'hoo' },
  { a: 2, b: 'y', c: 'joo' }
]

进入这个:

var out = [
  { a: 1, x: 'foo', y: 'goo' },
  { a: 2, x: 'hoo', y: 'joo' }
]

逻辑是所有元素都应该基于它们的a属性进行连接,并且所有bc属性分别表示应该合并到单个对象中的键/值对基于他们共享的a值。

5 个答案:

答案 0 :(得分:8)

您可以使用哈希对象,并使用reduce来包装哈希:



const arr = [
  { a: 1, b: 'x', c: 'foo' },
  { a: 1, b: 'y', c: 'goo' },
  { a: 2, b: 'x', c: 'hoo' },
  { a: 2, b: 'y', c: 'joo' }
];

let result = Object.values(             // the result is the values of the hash object
  arr.reduce((hash, o) => {             // hash is a hash object that make it easier to group the result
    hash[o.a] = hash[o.a] || {a: o.a};  // if there is no object in the hash that have the value of the key a equal to o.a, then create a new one
    hash[o.a][o.b] = o.c;               // set the value of the key stored in o.b to o.c
    return hash;
  }, {})
);

console.log(result);




答案 1 :(得分:5)

您可以使用带有Map

的闭包



var input = [{ a: 1, b: 'x', c: 'foo' }, { a: 1, b: 'y', c: 'goo' }, { a: 2, b: 'x', c: 'hoo' }, { a: 2, b: 'y', c: 'joo' }],
    output = input.reduce((map => (r, o) => (!map.has(o.a) && map.set(o.a, r[r.push({ a: o.a }) - 1]), map.get(o.a)[o.b] = o.c, r))(new Map), []);

console.log(output);

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




答案 2 :(得分:2)

您可以使用forEachObject.assigna分组,然后map分组,以返回对象值。



var data = [
  { a: 1, b: 'x', c: 'foo' },
  { a: 1, b: 'y', c: 'goo' },
  { a: 2, b: 'x', c: 'hoo' },
  { a: 2, b: 'y', c: 'joo' }
]

var r = {}
data.forEach(e => r[e.a] = Object.assign((r[e.a] || {}), {a: e.a, [e.b]: e.c}))
r = Object.keys(r).map(e => r[e])

console.log(r)




答案 3 :(得分:0)

不确定方法是优雅还是功能,但使用for..of循环返回预期结果,Array.prototype.some()Object.assign()

function props(array, key, prop1, prop2) {
  let arr = [];
  for (let obj of array) {
    let o = {};
    for (let {[key]:_key, [prop1]:_prop1, [prop2]:_prop2} of [obj]) {
      o[_prop1] = _prop2;
      o[key] = _key;
    }
    if (!arr.some(p => p[key] === o[key])) arr.push(o);
    for (let prop of arr) {
      if (prop[key] == o[key]) {
        prop = Object.assign(prop, o)
      }
    }
  }
  return arr
}

var _in = [
  { a: 1, b: 'x', c: 'foo' },
  { a: 1, b: 'y', c: 'goo' },
  { a: 2, b: 'x', c: 'hoo' },
  { a: 2, b: 'y', c: 'joo' }
];

console.log(props(_in, "a", "b", "c"));

答案 4 :(得分:0)

我喜欢提供的答案,但这是我的尝试。我相信它更具可读性,但它使用Object.assignObject.values

const input = [
  { a: 1, b: 'x', c: 'foo' },
  { a: 1, b: 'y', c: 'goo' },
  { a: 2, b: 'x', c: 'hoo' },
  { a: 2, b: 'y', c: 'joo' }
]

const map = input.reduce((acc, obj) => {
  const [a, key, value] = Object.values(obj)
  const newObj = {a, [key]: value}

  if (acc[a]) {
    Object.assign(acc[a], newObj)
  } else {
   acc[a] = newObj
  }

  return acc 
}, {})

console.log(Object.values(map))