将对象映射到ES6中的对象数组

Chr*_*ris 0 javascript ecmascript-6

如何在保留键名的同时将对象转换为对象数组?

// actual 
obj = {
  key1: null,
  key2: "Nelly",
  key3: [ "suit", "sweat" ]
} 

// expected 
arr = [
  { key2: "Nelly" },
  { key3: [ "suit", "sweat" ] }
]
Run Code Online (Sandbox Code Playgroud)

目前我的解决方案是......

 var arr = Object.keys(obj).map(key => { if (obj[key]) return { key: obj[key] } });
Run Code Online (Sandbox Code Playgroud)

返回

arr = [
  undefined,
  { key: "Nelly" },
  { key: [ "suit", "sweat" ] }
]
Run Code Online (Sandbox Code Playgroud)

nnn*_*nnn 8

.map()返回与原始数组长度相同的数组。像您这样带有回调的代码在某些情况下不返回值将导致元素具有 value undefined。处理这个问题的一种方法是首先.filter()列出您不想保留的元素。

无论如何,要获得您想要的键名,您可以使用具有计算属性名称的对象文字:

{ [key]: obj[key] }
Run Code Online (Sandbox Code Playgroud)

在上下文中:


Tha*_*you 5

传感器

这里有很多答案可以帮助您以实用的方式得出答案 - filtermap就是您所寻找的结果.使用原始for循环还有其他答案,但那些让你难过.

所以你想知道,"是否可以过滤映射而不必多次遍历数组?" 是的,使用传感器.


Runnable演示

如有必要,我可以使用更多代码说明更新此段落.ES6来找你......

// Trans monoid
const Trans = f => ({
  runTrans: f,
  concat: ({runTrans: g}) =>
    Trans(k => f(g(k)))
})

Trans.empty = () =>
  Trans(k => k)

const transduce = (t, m, i) =>
  i.reduce(t.runTrans((acc, x) => acc.concat(x)), m.empty())

// complete Array monoid implementation
Array.empty = () => []

// transducers
const mapper = f =>
  Trans(k => (acc, x) => k(acc, f(x)))
  
const filterer = f =>
  Trans(k => (acc, x) => f(x) ? k(acc, x) : acc)
  
const logger = label =>
  Trans(k => (acc, x) => (console.log(label, x), k(acc, x)))

// your function, implemented with transducers  
const foo = o => {
  const t = logger('filtering')
    .concat(filterer(k => o[k] !== null))
    .concat(logger('mapping'))
    .concat(mapper(k => ({ [k]: o[k] })))
    .concat(logger('result'))
  return transduce(t, Array, Object.keys(o))
}

console.log(foo({a: null, b: 2, c: 3}))
Run Code Online (Sandbox Code Playgroud)

输出; 注意步骤显示为隔行扫描 - 过滤,映射,结果,重复 - 这意味着每个组合的传感器都会为输入数组的每次迭代运行.还要注意因为a值是null,没有映射结果步骤a; 它直接跳过过滤 b - 所有这一切意味着我们只通过一次数组.

// filtering a
// filtering b
// mapping b
// result { b: 2 }
// filtering c
// mapping c
// result { c: 3 }
// => [ { b: 2 }, { c: 3 } ]
Run Code Online (Sandbox Code Playgroud)

整理起来

当然,这个foo功能有很多console.log东西.如果不是很明显,我们只想删除logger换能器以供实际应用

const foo = o => {
  const t = filterer(k => o[k] !== null)
    .concat(mapper(k => ({ [k]: o[k] })))
  return transduce(t, Array, Object.keys(o))
}

console.log(foo({a: null, b: 2, c: 3}))
// => [ {b: 2}, {c: 3} ]
Run Code Online (Sandbox Code Playgroud)

归因

我对这个主题的启示完全归功于Brian Lonsdorf和随附的工作:Monoidal Contravariant Functors实际上是有用的