Javascript 需要帮助从现有阵列创建新阵列吗
我有这样一个数组:Javascript 需要帮助从现有阵列创建新阵列吗,javascript,Javascript,我有这样一个数组: const foo = [{ cur: "GBT", val: [800, 450] }, { cur: "USD", val: 100 }, { cur: "EUR", val: 200 }, { cur: "GBT", val: [100, 250] }] 我想在上述阵列之外实现以下结构:
const foo = [{
cur: "GBT",
val: [800, 450]
},
{
cur: "USD",
val: 100
},
{
cur: "EUR",
val: 200
},
{
cur: "GBT",
val: [100, 250]
}]
我想在上述阵列之外实现以下结构:
[{
id: 0,
cur: "GBT",
val: 800
},
{
id: 1,
cur: "GBT",
val: 450
},
{
id: 2,
cur: "USD",
val: 100
},
{
id: 3,
cur: "EUR",
val: 200
},
{
id: 4,
cur: "GBT",
val: 100
},
{
id: 5,
cur: "GBT",
val: 250
}]
这就是我所尝试的:
foo.reduce((x, y, i, a) => {
let resObj = {};
if (Array.isArray(y.val)) {
let cnt = 0;
(a.indexOf(y) === 0 ? cnt : cnt += i)
for (let j = 0; j < y.val.length; j++) {
const obj = {};
obj["id"] = cnt;
obj["value"] = y.val[j]
obj["currency"] = y.cur;
x.push(obj);
cnt++;
}
} else {
let cnt = 1
resObj["id"] = i + cnt;
resObj["value"] = y.val;
resObj["currency"] = y.cur;
}
return x.concat(resObj)
}, [])
foo.reduce((x,y,i,a)=>{
设resObj={};
if(数组isArray(y.val)){
设cnt=0;
(a.indexOf(y)==0?cnt:cnt+=i)
对于(设j=0;j
观察到的错误
1.当reduce函数找到类型为array的对象的下一个val时,它不会增加计数器,因此id等于上一个计数器。
2.我还想知道,如果对象具有数组val,我如何避免创建空白对象,但不确定发生这种情况的实际原因是什么。
请查看结果附件
如果
val
属性是数组,则可以使用嵌套flatMap()
和嵌套map()
。获取1D数组后,使用map()
插入id
属性
const foo=[{
cur:“GBT”,
瓦尔:[800450]
},
{
cur:“美元”,
瓦尔:100
},
{
cur:“欧元”,
瓦尔:200
},
{
cur:“GBT”,
瓦尔:[100250]
}]
常量res=foo.flatMap(x=>Array.isArray(x.val)?
x、 val.map(val=>({cur:x.cur,val})):
{…x}
).map((x,id)=>({…x,id}))
console.log(res)
也可以通过将值作为数组来减少数组
var数据=[{cur:“GBT”,val:[800450]},{cur:“USD”,val:100},{cur:“EUR”,val:200},{cur:“GBT”,val:[100250]},
id=0,
结果=数据.reduce((r,{cur,val})=>{
[].concat(val).forEach(val=>{
r、 push({id,cur,val});
id++;
});
返回r;
}, []);
控制台日志(结果)代码>
.as控制台包装{max height:100%!important;top:0;}
Array.prototype.reduce()
可能会对您有所帮助reduce()
callback接受两个参数,第一个参数是旧的/以前的迭代值,第二个参数是当前的迭代值/元素
因此,使用这个函数,我们可以将当前迭代值保持为上一个迭代值(总值)
该方法对数组的每个元素执行一个reducer函数(您提供的),从而产生一个输出值
const foo=[{cur:“GBT”,val:[800450]},{cur:“USD”,val:100},{cur:“EUR”,val:200},{cur:“GBT”,val:[100250]}]
const result=foo.reduce((acc,cur)=>{
if(数组isArray(当前值)){
cur.val.map(val=>!!(acc.push({id:acc.length,cur:cur.cur,val:val})))
}否则{
acc.push({id:acc.length,cur:cur.cur,val:cur.val})
}
返回acc
}, [])
console.log(result)
您正在每次迭代中重置count的值,您可以将其从reduce中取出
const foo=[{cur:“GBT”,val:[800450]},{cur:“USD”,val:100},{cur:“EUR”,val:200},{cur:“GBT”,val:[100250]}]
设cnt=0;
设op=foo.reduce((x,y,i,a)=>{
if(数组isArray(y.val)){
对于(设j=0;j console.log(op)
您可以使用简单的方法来执行此操作,这不是非常有效,但也不会有什么影响,除非您正在处理具有数百个条目的数组,或者您可以使用高效的方法来执行此操作,并且您必须使用多个数据结构
简单的方法:
使用映射和返回数组,使{cur:“GBT”,val:[800450]}
变成[{cur:“GBT”,val:800},{cur:“GBT”,val:450}
flat()
-将结果设置为[[{…},{…}],{…},[{…},{…}]
变为[{…},{…},{…},{…},{…}]
再使用一个映射添加增量id
属性
由于.flatMap
的存在,我们可以将步骤1和2转化为单个步骤
因此,在代码中:
function mapFn(e) {
if (!e.v.map) return e;
return e.v.map(val => ({cur: e.cur, val}));
};
function convertData(input) {
return array.flatMap(mapFn).map((e,id) => {
e.id = id;
return e;
});
}
很好,很简单,但是两张地图的效率比一张地图低。因此,如果我们想避免这种情况:
从一个空的目标数组和一个负责id
管理的条目添加函数开始,然后
然后遍历原始数组,分别展开和处理每个条目
代码:
function convertData(input) {
const output= [];
const addEntry(e) {
e.id = output.length;
output.push(e);
};
input.forEach(e => {
result = mapFn(e); // this is the same mapFn as above
if (result.forEach) {
result.forEach(addEntry);
} else {
addEntry(entry);
}
});
return output;
}
请注意,您可以使用.reduce()
来“减少代码”,但这样做不会提高效率。试试这个普通的方法
var数据=[{cur:“GBT”,val:[800450]},{cur:“USD”,val:100},{cur:“EUR”,val:200},{cur:“GBT”,val:[100250]}];
设r=[],计数器=1;;
data.map((d,i)=>{
设dummy={};
if(数组isArray(d.val)){
虚拟['id']=计数器++;
虚拟['cur']=d.cur;
虚拟值['val']=d.val[0];
r、 推(假);
虚拟={};
虚拟['id']=计数器++;
虚拟['cur']=d.cur;
虚拟['val']=d.val[1];
r、 推(假);
}否则{
虚拟['id']=计数器++;
虚拟['cur']=d.cur;
虚拟['val']=d.val;
r、 推(假);
}
返回0;
});
console.log(r);
简化的备选方案:
var id=0,arr=[{cur:“GBT”,val:[800450]},
{cur:“USD”,val:100},
{cur:“EUR”,val:200},
{cur:“GBT”,val:[100250]}]
var result=arr.flatMap(o=>[o.val].fla