getting the value/key from a dynamic map object in immutable.js - javascript

I have a dynamic immutable object and I want to know a better way to get a deep-level value. Fiddle Example
var map = {aaa:{bbb:{ccc:'ddd'}}}
map = Immutable.fromJS(map)
Suppose that I don't know the third-level key ccc, what is the best way to get its value, which in this case ddd?
var map = {aaa:{bbb:{ccc:'ddd'}}}
map = Immutable.fromJS(map)
map.keySeq().toList().map(first=>{
map.get(first).keySeq().toList().map(second=>{
map.getIn([first,second]).valueSeq().toList().map(third=>{
alert(third)
})
})
})
Is the above example an appropriate way to get the value ddd. I can't simply use map.getIn(['aaa','bbb','ccc']) because this map object is dynamic in my situation

As I understand, you're trying to obtain the key which has ddd value. If you're aware of the object nesting levels, you can simply flatten it.
var map = {aaa:{bbb:{ccc:'ddd'},eee:{fff:'ggg'}}};
var map = map.flatten(3);
/// {
/// ccc: "ddd",
/// fff: "ggg"
/// }
Now, simply filter the map and obtain requisite key.

Related

Using ECMA6 Set as object key

Is there a way to use Set as object keys
let x = {}
const a = new Set([3, 5])
x[a] = 1
console.log(x) // >{[object Set]: 1}
const b = new Set([1, 4])
x[b] = 2
console.log(x) // >{[object Set]: 2}
The keys are being overwritten even though the sets are not equal.
Thanks!
No this is not possible because Object keys must be strings or symbols. If you would like to use a Set as a key you can try using a Map. Maps are similar to objects except you can use other objects as keys for a map.
One thing to keep in mind is that you cannot use maps exactly like you use Objects.
This is directly from the Mozilla docs.
The following IS NOT A VALID USE OF A MAP.
let wrongMap = new Map()
wrongMap['bla'] = 'blaa'
wrongMap['bla2'] = 'blaaa2'
console.log(wrongMap) // Map { bla: 'blaa', bla2: 'blaaa2' }
But that way of setting a property does not interact with the Map data structure. It uses the feature of the generic object. The value of 'bla' is not stored in the Map for queries. Other operations on the data fail:
Correct use of a map looks like the below:
let map = new Map()
// setting values
map.set(key, value)
// getting values
map.get(key)
Remember that if you use an Object like a Set as a key, the reference of the Set is what matters.
If you instantiate two sets separately, even if they both have the same contents, they will have different references and be considered different keys.
Do you mean that the map in ES6 like this:
x = new Map()
a = new Set([3, 5])
x.set(a, 1)
console.log(x);

How to append values to ES6 Map

I am trying to learn about ES6 Map data structures and am having difficulty understanding some of their behaviour. I would like to create a Map with an Array as a value and append (push) new values onto the current value of the Map. For example:
let m = new Map()
m.set(1, []) // []
m.set(1, m.get(1).push(2)) // [[1, 1]]
I am confused as to why I do not get [2] as the value of m.get(1) above. How can I append values to the array in my map?
That's because the method push returns the size of the array after the insertion.
You can change your code to the following to append to an array:
m.get(1).push(2);
And it'll update the value in the map, there's no need to try to re-set the value again as the value is passed back as reference.
The best way to define a Map according to your need is to explicitly tell the Map, what kind of data you want to deal with.
in your case you want values in an array, we could get using a "string id" for example
In this case you will have this :
let map = new Map<String, Array<any>>
Then you can create items like map["key"] = ["lol", 1, null]
There is two thing. First as #Adriani6 said the push method do not returns a pointer to the array but the size of the array.
Secondly, you do not need to do an other m.set, because your push will affect directly the array behind the reference returned by m.get
function displayMap(m) {
m.forEach(function(val, key) {
console.log(key + " => " + val);
});
}
let m = new Map();
m.set(1, []);
displayMap(m);
m.get(1).push(20);
displayMap(m);
It fails, because the return of push() is the size of the array after push.
You can push the content after doing a get().
m.get(1).push(2);
If you want to test set() then write a a self executable function like this:
let m = new Map()
m.set(1, []) // []
console.log(m.get(1))
m.set(1, (() => {m.get(1).push(2);return m.get(1);})());
console.log(m.get(1))
Here's a working example of what you are trying to do (open console)
Have a look here. As you can see the push method returns the new length of the array you just mutated, hence your result.

Creating object with varying keys

I want to create object similar to this using loop, where I have separate array of country codes and another array of latitude and longitudes
is there any way to achieve this in typescript,
var latlong={
'us': {'latitude':39.528019315435685, 'longitude':-99.1444409552122},
'fr': {'latitude':46.62065825554313, 'longitude':2.4521888685061306}
}
Assuming that your arrays have corresponding index, then you can use this sample code,
let country = ['us','fr'];
let lat = ['39.528019315435685','46.62065825554313'];
let long = ['-99.1444409552122','2.4521888685061306'];
let latlong = {};
country.forEach((code,index)=>{
latlong[code] = {};
latlong[code]['latitude'] = lat[index];
latlong[code]['longitude'] = long[index];
})
Assuming that both arrays are correctly mapped through their indices, you could try :
coordinatesArray.forEach((coordinate, index)=>{
latlong[countryArray[index]] = coordinate;
});
where coordinatesArray contains an array of latitude and longitude objects and countryArray contains the country string.
Here's small example of way to create desired object.
CodeSandbox-project
Basically you iterate through other array and with index reference to your other array. with obj[key] you can create object with variables as keys.
And just to open a bit discussion about achieving this in TypeScript. TypeScript basically only extends existing EcmaScript-syntax with types so this would work in vanillaJS or in TypeScript as expected. Benefit you get in TypeScript is if you would have typed your variables.
eg.
const country: string[] = ['fr','en']
So now your IDE can show you that you expect country-variable only to contain strings.

How to serialize a Map in javascript?

So...there is this type in js called Map and it is really nice...it is faster than an Object for iterations and calculations so I really like it. However...you can't pass Maps around as you could with objects.
I know that I could turn Map into JSON but it is costly to do so and it kind of looses the point of using Maps in the first place.
JSON format is not meant for Maps...it was meant for Objects.
So...lets move from the JSON format a little.
Is there a way for me to serialize a Map into a string in any way so that I can then do the opposite - from said serialized Map to end up with a Map
Preferably this method should be as easy to perform as JSON.stringify or its counterpart JSON.parse.
I want to use Map as it is faster and better but I need to send my data as string. The format of the string is not important as long as I can parse it back into a Map
-- edit: Added the missing JSON Stringify function during serialization -
There is a native way of doing this in Javascript.
the Map object has a method called entries() that returns an iterator that will yield each entry in the map as an array with 2 values in it. It will look like [key, value].
To avoid writing any looping code yourself, you can use Array.from() which can consume an iterator and extract each item from it. Having that, the following will give you your Map object in a serialized form.
let mySerialMap = JSON.stringify(Array.from(myMap.entries()))
console.log(mySerialMap)
Now, that's not even the coolest part. But before getting there, let me show you one possible way of using the Map constructor.
let original = new Map([
['key1', 'the-one-value']
['second-key, 'value-two']
])
The array of array that you can see being passed to the Map object is in the same format as what you get from using Array.from(myMap.entries()).
So you can rebuild you map in a single line using the following sample code:
let myMap = new Map(JSON.parse(mySerialMap))
And you can use myMap as you would any Map.
let myMap = new Map(JSON.parse(mySerialMap))
let first = myMap.get('some-key')
myMap.set('another-key', 'some value')
I guess the whole point of Maps/Dictionaries is that you can use objects as keys in them, so:
let a = {}, b = {}, m = new Map();
m.set(a,b);
m.get(a); // b
So you get b since you have a reference on a. Let's say you serialize the Map by creating an Array of arrays, and stringify that to json:
function serialize (map) {
return JSON.stringify([...map.entries()])
}
let s = serialize(m); // '[[{}, {}]]'
// '[[<key>, <val>], … ]'
Than you could:
let m2 = JSON.parse(s).reduce((m, [key, val])=> m.set(key, val) , new Map());
But the question now is: How to get a certain key? Since there does not exist any reference, due to the fact that all objects have been stringified and recreated, it is not possible to query a dedicated key.
So all that would only work for String keys, but that really takes most of power of maps, or in other words, reduces them to simple objects, what is the reason maps were implemented.
To #philipp's point, people who care about the serialization of the Map will probably prefer objects (leverages intuition, reduces '[]' arithmetic). Object.entries() and Object.fromEntries() can make that a bit more literate:
writeMe = new Map()
writeMe.set('a', [1])
writeMe.set('b', {myObjValue: 2})
// ▶ Map(2) {'a' => Array(1), 'b' => {…}}
written = JSON.stringify(Object.fromEntries(writeMe.entries()))
// '{"a":[1],"b":{"myObjValue":2}}'
read = new Map(Object.entries(JSON.parse(written)))
// ▶ Map(2) {'a' => Array(1), 'b' => {…}}
read.get("b")
// ▶ {myObjValue: 2}

Reading an object's value in JavaScript

I want to get the features from my layer. So I'm requesting WMSGetFeatureInfo method after a successful request for GetFeatureInfo on my layer.
The returned object is structured like this:
I can read values like BEVDICHTE with var bevdichte = features.BEVDICHTE and so on.
But when I want to get the value of the_geom with var the_geom = features.the_geom it returns an object. Yes it is nested so this is intended but my question is how to get the value ol.geom.MultiPoint
from the_geom?
EDIT:
Unfortunately var target = features.the_geom['actualEventTarget_']; will just return another 'actualEventTarget_' object. This is because the the_geom object is nested into infinity. I attached another screenshot to describe my problem. There are many more nested eventTargets following. Yet I was not able to get the property ol.geom.MultiPolygon.
To access a nested array, just use brackets: '[ ]'
var nestedArray = [[1,2], [3,4]];
var nestedArrayValue = nestedArray[0][0];
// --> returns 1
With your example:
var target = features.the_geom['actualEventTarget_']
By the way, from the looks of it var the_geom = features.the_geom doesn't seem like an array. It has keys, mapped to a value, are you sure this is an array, not an object?

Categories

Resources