【问题标题】:Creating objects by splitting an object whose attributes are arrays [closed]通过拆分属性为数组的对象来创建对象[关闭]
【发布时间】:2019-12-18 12:30:47
【问题描述】:

我有一个对象数组,其属性是数组(可变长度),我想用通过组合数组属性中存在的元素创建的新对象(在同一个数组中)替换这些对象。 我正在使用 js 类的函数,这就是为什么你会看到“this”。 人们建议我使用 .reduce() 和 .map(),但我不知道如何使用它们。 这是目标:


    this.apple="apple"

    this.Array=[ 
      { names:[something1, something2...]
        fruit:this.apple
        features:[feature1,feature2,...]
      }
    ]

预期的输出是:

      // (expected output):

    this.Array=[
      { names:something1,
        fruit:this.apple
        features:feature1
      },
      { names:something1,
        fruit:this.apple
        features:feature2
      },
      { names:something2,
        fruit:this.apple
        features:feature1
      },
      { names:something2,
        fruit:this.apple
        features:feature2
      },
      ...
    ]

【问题讨论】:

  • 没有清楚你想要什么,请解释清楚。
  • 我有一个对象 (this.Array),其属性(名称、功能)是数组。我想把这个对象分成多个对象,这些对象的属性只有前一个数组属性的一个元素。当我编码时,我希望对象变成四个不同的对象,这些对象由前一个对象的属性中存在的元素组合创建

标签: javascript arrays


【解决方案1】:

使用flatMap 可以取消对数组中的元素进行分组..

const fruit = 'apple'

const array=[ 
  { names:['something1', 'something2'],
    fruit: fruit,
    features:['feature1','feature2']
  }
]

array.flatMap(({names,fruit,features}) => {
  names.flatMap(name => {
    features.flatMap(feature => {
      console.log(({name,fruit,feature}));
    })
  })
})

【讨论】:

  • 你的代码完全符合我的要求,但事实是我在一个 js 类中工作,所以我不能声明 const。你能像在 js 类中一样修改你的代码 sn-p 吗?
  • @Drun,用this 替换const 关键字,就像您发布的问题一样。将const array 更改为this.Array .. 在this.Array = [ ... ] 之后使用flatMap 解决方案..
  • 我试过了,但它给了我错误“names.flatMap 不是函数”,因为它不知道“名称”是什么
  • @Drun,你确定names 是一个数组吗?您可以像我为您的解决方案 codepen.io/Maniraj_Murugan/pen/abzpLQm 创建的那样在 codepen 中创建任何示例。如果可能的话,用您的结果修改它..
  • @Drun,如果array.flatMap 有效,那么它也应该在names.flatMap 中有效,因为flatMap 已经识别出array.flatMap.. 似乎名称不是正确的数组..
【解决方案2】:

一种可能的方法是递归遍历所有键,并为每个键生成一个或多个对象(取决于输入是值还是数组):

function combine(obj,keys,idx,arr,proto){
  arr=arr || [];
  proto=proto || {};
  keys=keys || Object.keys(obj);
  idx=idx || 0;
  if(idx>=keys.length){
    arr.push(Object.assign({},proto));
  }
  else {
    let key=keys[idx++];
    let vals=obj[key];
    if(Array.isArray(vals))
      for(let v of vals){
        proto[key]=v;
        combine(obj,keys,idx,arr,proto);
      } else {
        proto[key]=vals;
        combine(obj,keys,idx,arr,proto);
      }
  }
  return arr;
}

let org={
  name:["something1", "something2"],
  fruit:"apple",
  feature:["feature1","feature2"],
};

console.log(...combine(org));

【讨论】:

    【解决方案3】:

    .map() 将是处理此问题的最佳方法,但是我很快就写了这个,因为我的时间有限:

    let apple = "apple";
    
    let Array = [
        {
            name: ["something1", "something2"],
            fruit: this.apple,
            features: ["feature1", "feature2"]
        }
    ];
    
    let somethings = [];
    let features = [];
    
    Array[0].name.forEach(item => {
        somethings.push(item);
    });
    
    Array[0].features.forEach(item => {
        features.push(item);
    });
    
    let newtest = [];
    for (let index = 0; index < somethings.length; index++) {
       newtest.push({
            name: somethings[index],
            fruit: apple,
            features: features[index]
       })
    }
    
    console.log(newtest);
    

    上面的代码将在不使用 .map() 的情况下完成您的要求; 简而言之,这是做什么的:

    我们从初始对象中拆分出 2 个数组,然后通过循环创建一个新数组,然后将相同的索引添加到同一个对象。不确定这是否正是您想要的。

    结果如下:

    [
      { name: 'something1', fruit: 'apple', features: 'feature1' },
      { name: 'something2', fruit: 'apple', features: 'feature2' }
    ]
    

    【讨论】:

      猜你喜欢
      • 2022-12-04
      • 2021-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2019-04-15
      • 2023-02-09
      相关资源
      最近更新 更多