Creating objects by splitting an object whose attr

2020-01-20 13:13发布

问题:


Want to improve this question? Add details and clarify the problem by editing this post.

Closed last month.

I have an array of objects whose attributes are arrays (of variable length) and I want to replace those objects with new ones (in the same array) created by combining the elements present in the array-attributes. I'm working in a function of a js class, that's why you see "this." People suggested me to use .reduce() and .map(), but I didn't figure out how to use them. Here's the goal:


    this.apple="apple"

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

And the expected output would be:

      // (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
      },
      ...
    ]

回答1:

Using flatMap you can ungroup the elements in an array..

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}));
    })
  })
})



回答2:

A possible approach would be recursively go through all the keys, and generate one or more objects for each (depending on the input is a value or an array):

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() would be the optimal way to handle this however I quickly wrote this cause I have limited time:

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);

The above code will do what you require without using .map(); In short what this does:

We split the 2 arrays from the initial object, when then create a new array by looping and then adding the same indexes to the same object. Not sure if this is exactly what you wanted.

The result would be the below:

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