Javascript rewriting an array

Viewed 492

I have two arrays that are dynamic which could change at any time. For example:

var vehicleColor = "red,green,blue,white".split(",");
var vehicleType = "Truck,Car,Bus".split(",");

How can I incorporate these arrays to make a javascript array in this format for my graph.

var links = [
    {source: vehicleColor[0], target: vehicleType[0]},
    {source: vehicleColor[1], target: vehicleType[0]},  
    {source: vehicleColor[2], target: vehicleType[0]},
    {source: vehicleColor[3], target: vehicleType[0]},  
    {source: vehicleColor[0], target: vehicleType[1]},
    {source: vehicleColor[1], target: vehicleType[1]},
    etc...
]

Basically I need an array that loops through all of the elements in both arrays but creating a separate line for each one.

I've tried:

links = links.map(x => ({source:vehicleColor, target:vehicleType}));

but this doesn't get me each element in a separate line.

The map method gives me this output

var links = [
    {source: ["red","green","blue","white"], target: ["Truck","Bus","Car"]},
]
4 Answers

You'd use nested loops:

var vehicleColor = "red,green,blue,white".split(",");
var vehicleType = "Truck,Car,Bus".split(",");

var links = [];
for (var i = 0; i < vehicleType.length; ++i) {
  var type =  vehicleType[i];
  for (var j = 0; j < vehicleColor.length; ++j) {
    links.push({
      source: type,
      target: vehicleColor[j]
    });
  }
}

console.log(links);

You could take a recursive function which separates all key/value pairs and build a new cartesian product by iterating the values, if an array with objects call getCartesian again and build new objects.

function getCartesian(object) {
    return Object.entries(object).reduce((r, [k, v]) => {
        var temp = [];
        r.forEach(s =>
            (Array.isArray(v) ? v : [v]).forEach(w =>
                (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                    temp.push(Object.assign({}, s, { [k]: x }))
                )
            )
        );
        return temp;
    }, [{}]);
}

var data = { source: ["red", "green", "blue", "white"], target: ["Truck", "Bus", "Car"] };

console.log(getCartesian(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }

I used a foreach and map to get the desired result

var vehicleColor = "red,green,blue,white".split(",");
var vehicleType = "Truck,Car,Bus".split(",");

let res = [];
vehicleColor.forEach((color) => {
     res = res.concat(vehicleType.map((type) => {
       return {'source': color, 'target': type}
    }))
 })
 
 console.log(res)

You may run two run two loops. For example when taking each color as a constant run the complete loop for vehicle, then repeat the same for another color

var vehicleColor = "red,green,blue,white".split(",");
var vehicleType = "Truck,Car,Bus".split(",");

let links = [];
vehicleColor.forEach(function(item) {
  vehicleType.forEach(function(ve) {
    links.push({
      source: item,
      target: ve
    })
  })
})
console.log(links)

Related