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;jconsole.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