Home > Enterprise >  Replace names of array objects dynamically by string content
Replace names of array objects dynamically by string content

Time:11-24

To reduce my last question (it was a bit complicated). Is it possible to change the names of "array objects" dynamically?

I have a list of variables (structure must stay like this way):

var markers = []
var markerHouse = ... markers.push(markerHouse);
var markerAnimal = ... markers.push(markerAnimal);
var markerCar = ... markers.push(markerCar);
// aso.

I tried lots of ways to change the array object names, like this one:

var NewMarkers = "markerHouse, markerAnimal"; // string content, generated by a function
var NewMarkersArray = NewMarkers.split(","); // create array of this string
var NewGroup = L.layerGroup([NewMarkersArray]); // request for array of objects

The result of NewGroup is:

L.layerGroup(["markerHouse", "markerAnimal"]);

And I get a "TypeError: cannot use 'in' operator to search for "_leaflet_id" in "markerHouse" ...

But what I need is:

L.layerGroup([markerHouse, markerAnimal]);

CodePudding user response:

Using eval() as suggested in other questions is considered a bad practice.

The most straightforward way to retrieve a global variable by it's string name is from 'window'. A global variable is actually a property of the 'window' object.

So you could do:

L.layerGroup( [ window["markerHouse"], window["markerAnimal")] ]);

And with dynamic variable names:

var dynamicallyGeneratedArrayOfVarNames = "markerHouse,markerAnimal".split(',');
L.layerGroup( [ window[dynamicallyGeneratedArrayOfVarNames[0]], window[dynamicallyGeneratedArrayOfVarNames[1])] ]);

See snippet below:

var markerHouse = 'markerHouse content';
var markerAnimal = 'markerAnimal content'

console.log(window['markerHouse']);
console.log(window['markerAnimal']);

// And with dynamically retrieved names
var NewMarkers = "markerHouse, markerAnimal"; // string content, generated by a function
var NewMarkersArray = NewMarkers.split(", "); // create array of this string
console.log(window[NewMarkersArray[0]])
console.log(window[NewMarkersArray[1]])

Still, if you have the luxury of refactoring the initial code, the best practice would be to store the variables by name on creation e.g.:

const myvars = {}
myvars.markerHouse = "any type of marker house data"
myvars.markerAnimal = "any type of marker animal data"

L.layerGroup( [ myvars["markerHouse"], myvars["markerAnimal")] ]);

CodePudding user response:

Do you need eval?

L.layerGroup([eval("markerHouse"), eval("markerAnimal")]);

CodePudding user response:

Keep your values in an object:

const allMarkers = {
    house: whatever,
    animal: whatever,
    boat: whatever,
    // ...
 };

 let markerNames = ["house", "boat"];

 let markers = markerNames.map(name => allMarkers[name]);

Then:

  let newGroup = L.layerGroup(markers);

The allMarkers object contains the actual values corresponding to the named variables in your original code. They can be accessed by name dynamically because objects in JavaScript inherently provide that feature. The list of marker names can therefore be transformed into a list of the actual values with that simple .map() call.

CodePudding user response:

If you really can't change what you've got, then I'd probably maintain a map of keys for every variable.

const vars = {
  'markerHouse': markerHouse,
  'markerAnimal': markerAnimal,
};

Or even nicer:

const vars = {markerHouse, markerAnimal};

Then:

var NewGroup = L.layerGroup(NewMarkersArray.map(v => vars[v]));

If that's infeasible, then you'll have to use eval or window['markerHouse']. Those both feel terrible though and suggest has gone wrong somewhere along the way.

  • Related