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

Javascript 将对象映射到ES6中的对象数组,javascript,ecmascript-6,Javascript,Ecmascript 6,如何在保留键名的同时将对象转换为对象数组 // actual obj = { key1: null, key2: "Nelly", key3: [ "suit", "sweat" ] } // expected arr = [ { key2: "Nelly" }, { key3: [ "suit", "sweat" ] } ] 目前我的解决方案是 var arr = Object.keys(obj).map(key => { if (obj[key]) re

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

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

// expected 
arr = [
  { key2: "Nelly" },
  { key3: [ "suit", "sweat" ] }
]
目前我的解决方案是

 var arr = Object.keys(obj).map(key => { if (obj[key]) return { key: obj[key] } });
返回

arr = [
  undefined,
  { key: "Nelly" },
  { key: [ "suit", "sweat" ] }
]
.map()
返回与原始数组长度相同的数组。类似于您的代码,在某些情况下,带有不返回值的回调的代码将导致值未定义的元素。处理这个问题的一种方法是首先
.filter()
将不想保留的元素过滤掉

无论如何,要获得所需的键名,可以使用对象文字和:

在这方面:

const obj={
键1:null,
键2:‘耐莉’,
键3:[“西装”、“汗水”]
}
const arr=对象密钥(obj)
.filter(v=>obj[v]!=null)
.map(key=>({[key]:obj[key]}))

console.log(arr)
正如@zerkms所说,我认为使用多个es6函数不会改善代码。试试循环

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

let arr = [];
let k = Object.keys(obj);

for(let i = 0, len = k.length; i < len; i++) {
  let key = k[i];
  if (obj[key]) {
    arr.push({key: obj[key]});
  }
}
//实际的
设obj={
键1:null,
键2:“耐莉”,
键3:[“西装”、“汗水”]
};
设arr=[];
设k=Object.keys(obj);
for(设i=0,len=k.length;i
如果使用
映射
,预期数组的长度将与输入中的键数相同。因此,在这种情况下,
map
是不合适的。我的解决方案是使用如下的reduce函数:

var obj={
键1:null,
键2:‘耐莉’,
键3:[“西装”、“汗水”]
} 
var res=Object.keys(obj).reduce(
(会计科目,当前)=>{
//如果当前键的值不为null
//将对象插入到生成的数组中
if(obj[curr]){
acc.push({[curr]:obj[curr]});
返回acc;
}
//如果它们的键值为空,则跳过它
返回acc;
}, [] );

控制台日志(res)传感器

这里有大量的答案可以帮助你以实用的方式找到答案–
过滤
这个,
映射
那个,瞧,你在寻找的结果。还有其他一些答案是使用primitive
进行循环,但是这些让你很难过

所以你想知道,“有没有可能过滤映射而不反复遍历数组?”是的,使用传感器


可运行演示

如果有必要,我可能会用更多的代码解释来更新这一段。ES6向你走来

//反幺半群
常数Trans=f=>({
runTrans:f,
concat:({runTrans:g})=>
反式(k=>f(g(k)))
})
Trans.empty=()=>
Trans(k=>k)
常数转换=(t,m,i)=>
i、 减少(t.runTrans((acc,x)=>acc.concat(x)),m.empty()
//完整数组幺半群实现
Array.empty=()=>[]
//传感器
常量映射器=f=>
Trans(k=>(acc,x)=>k(acc,f(x)))
常数过滤器=f=>
变速器(k=>(acc,x)=>f(x)?k(acc,x):acc)
常量记录器=标签=>
Trans(k=>(acc,x)=>(console.log(label,x),k(acc,x)))
//你的功能,用传感器实现
常量foo=o=>{
常量t=记录器('筛选')
.concat(过滤器(k=>o[k]!==null))
.concat(记录器(“映射”))
.concat(映射器(k=>({[k]:o[k]})))
.concat(记录器(“结果”))
返回转换器(t、数组、对象键(o))
}

log(foo({a:null,b:2,c:3}))
我不相信显示的代码会返回您所说的内容:它将返回一个包含三个元素的数组,其中第一个元素的值
未定义
。首先使用普通的旧循环实现它。当你得到一个有效的解决方案时,你可以尝试“改进”它。为了澄清@nnnnnn的意思,
arr
的第一个节点是
undefined
谢谢,忘了把它放在那里了。我如何才能返回期望值?从简单的开始:您能以任何方式实现它吗?要求使用您还不了解的概念向您展示解决方案几乎不会教您如何使用这些概念。
如果它们的键值为null,请跳过它。
。。。或
0
false
''
或…在这种情况下,键名不会是
key2
key3
。到处都是钥匙。你可以检查一下,我不认为@zerkms是这么说的。我认为关键是,如果我们一直在思考如何做一些事情,回到普通循环可以让我们更容易理解所需的逻辑。接下来,通过添加/链接几个数组方法来代替循环可以被认为是一种改进,如果它使最终的代码更容易理解的话。这个主题对我来说非常有趣,但是已经很晚了,我不得不睡觉了。如果你需要任何额外的帮助,只要问问你的答案总是值得投票的;你总是让我想些什么。我发现这段代码令人困惑(除了简单的foo()函数),但很有趣,所以我将继续研究它。您能谈谈与单独过滤然后映射相比,这是如何执行的吗?(一方面,它只迭代一次而不是两次,但另一方面,每次迭代似乎都会有更多的函数调用。)@nnnnnn这是一种恭维,谢谢^ ^我很高兴再写一些关于这个主题的文章。“我很快就会讲的。@用户3297291开始学习使用组合器读/写程序肯定很棘手。在大多数情况下,使用单个字母有目的地命名变量,因为更具体的单词/名称会削弱(combinator)函数的泛型(多态)性质。这表明函数的表达式如何表示术语的组合,而不关心实际术语是什么。在命令式程序中,这将是一场噩梦,但由于每个函数(如上)都只是一个表达式,因此随着时间的推移,查看变量如何组合在一起变得越来越容易。@user3297291 I,但如果您有任何其他问题,请随时提问^_^
// actual 
let obj = {
  key1: null,
  key2: "Nelly",
  key3: [ "suit", "sweat" ]
};

let arr = [];
let k = Object.keys(obj);

for(let i = 0, len = k.length; i < len; i++) {
  let key = k[i];
  if (obj[key]) {
    arr.push({key: obj[key]});
  }
}