With map.set(key, value) you can add (or overwrite) a value for a specific key in the map.
If you have a big list of key-value pairs you need to add them all to the list separately:
[['keyA', 'valueA'],
['keyB', 'valueB'],
['keyC', 'valueC']].forEach(pair => map.set(...pair))
This does not look very performant as it involves a lot function calls.
Is there a faster way to do this?
You could take the array directly for a new Map instance.
var keyValues = [['keyA', 'valueA'], ['keyB', 'valueB'], ['keyC', 'valueC']],
map = new Map(keyValues);
console.log([...map]);
Related
I have some code that uses jQuery and needs re-writing to use native JS but I am having trouble with one section of it where what it does is:
Obtains the form data
Sorts the keys alphabetically
Loops through the elements to create a new array of items based on the form
This is what works in jQuery:
let formData = $('#TheForm').serialize();
let formItems = formData.split("&");
formItems.sort();
for (const element of formItems) {
//Do stuff here
}
This is what I have so far in native JS that does not yet work:
var theForm = document.getElementById('TheForm');
let formData = new FormData(theForm);
let formItems = formData.entries();
//formItems.sort(); <-- Can't work out a way to do this
for (let [key, value] of formItems) {
//Do stuff here
}
I think once I can figure out a way to sort the entries this will hopefully work and the code in the for loop can be simplified as it is having to extract the key and value on the = sign (from element) currently but in the new version the key and value are already separate.
The reason I am sorting the keys is because this form submits to the Barclays payment system (EPDQ) and requires the form elements to be in alphabetical order and I must also encrypt them, sending both the unencrypted and encrypted values where the server only accepts the data if the encrypted version matches when the remote server performs the same function. Within the loop I am populating both encrypted and unencrypted arrays so it is easier to sort at this point rather than later.
Thanks I really appreciate the help (below).
Since the entries function returns an Iterator, you'll first want to get an Array from that:
const formItems = Array.from(formData.entries())
At this point you have an Array of pairs, each pair being a tuple, an Array where the first element represents the "key" and the second one the "value". This is good though, because you now have an array on which you can call the sort function, that just so happens to be able receive a comparator function!
const sortedItems = formItems.sort(
([leftKey], [rightKey]) => leftKey > rightKey ? -1 : 1
)
The sort function is receiving an arrow function, where the two parameters (the two items being compared) are destructured in order to extract the first value of each of them into a variable - each of them being a pair, an array of two values, this works out just fine.
I have an Immutable list that populates a drag and drop list feature (there are no id's on the list item aside from their indices when mapping through them).
const list = Immutable.List([{"alias":"cat"},{"alias":"dog"},{"alias":"rat"}])
On dragEnd, the event gives me an array of the new order of the list, but does not give me anything to really identify the list items, aside from referencing the indices of the previous order.
const newOrder = [{"order":1},{"order":0},{"order":2}]
I need to dispatch a new re-ordered Immutable data list based on these indices to update my store, but have yet to find an eloquent and succinct way to do this. I was thinking perhaps some use of sortBy or maybe creating an orderedMap from the first list and referencing it from the newOrder array to create the orderedList?? Haven't been able to get anything to work that seems like a good solution.
Need to dispatch:
const orderedList = Immutable.List([{"alias":"dog"},{"alias":"cat"},{"alias":"rat"}])
What would be the best way to do this?
I think you can use map:
const newOrder = [{"order":1},{"order":0},{"order":2}];
const ordered =
Immutable.List([1,2,3])
.map(
(item,index,all)=>
all.get(newOrder[index].order)
);
console.log(
JSON.stringify(
ordered.toArray(),
undefined,
2
)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.min.js"></script>
I use list comprehension often in Python specifically to create a list from a dictionary of key values, in a sorted manner, I define the sorted keys in a list and use comprehension to get a sorted list, I have been looking around but could not find a similar method of doing the following in Javascript other than using a map:
Is there a better way to do this in Javascript?
In Python:
d = {'k2':'v2','k4':'v4','k3':'v3','k6':'v6','k5':'v5'}
list_keys=['k1','k2','k3','k4','k5','k6']
list_wanted_values = [d[c] for c in list_keys]
#list_wanted_values=['v1','v2','v3','v4','v5','v6']
In Javascript:
var js_list_wanted_values = list_keys.map(function(k){
js_list_wanted_values[k] = d[k]
)}
maybe this
var js_list_wanted_values = list_keys.map(k => d[k])
Your map should be more like
var js_list_wanted_values = list_keys.map(function(k){
return d[k]
})
map() creates a new array by returning a new value based on value of each element in array being iterated
I am using the immutable Map from http://facebook.github.io/immutable-js/docs/#/Map
I need to get an array of the values out to pass to a backend service and I think I am missing something basic, how do I do it ?
I have tried :
mymap.valueSeq().toArray()
But I still get an immutable data structure back ?
For example :
var d = '[{"address":"10.0.35.118","cpus":4}]';
var sr = JSON.parse(d);
var is = Immutable.fromJS(sr);
console.log(sr);
console.log(is.toArray());
console.log(is.valueSeq().toArray());
See this http://jsfiddle.net/3sjq148f/2/
The array that we get back from the immutable data structure seems to still be adorned with the immutable fields for each contained object. Is that to be expected ?
Just use someMap.toIndexedSeq().toArray() for getting an array of only values.
It's because the sr is an Array of Object, so if you use .fromJS to convert it, it becomes List of Map.
The is.valueSeq().toArray();(valueSeq is not necessary here.) converts it to Array of Map, so you need to loop through the array, and convert each Map item to Array.
var d = '[{"address":"10.0.35.118","cpus":4}]';
var sr = JSON.parse(d);
// Array of Object => List of Map
var is = Immutable.fromJS(sr);
console.log(sr);
console.log(is.toArray());
// Now its Array of Map
var list = is.valueSeq().toArray();
console.log(list);
list.forEach(function(item) {
// Convert Map to Array
console.log(item.toArray());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.5/immutable.min.js"></script>
Map.values() returns an ES6 Iterable (as do Map.keys() and Map.entries()), and therefore you can convert to an array with Array.from() or the spread operator (as described in this answer).
e.g.:
Array.from(map.values())
or just
[...map.values()]
Couldn't think of better title.
Important to note: I'm new to js and I guess its the reason I can't figure it out by myself.
I have a JSON array returned from a database, the JSON array represent a set of points.
Example of the JSON array:
var JSON_array = [{lat:1,lng:2}, {lat:1,lng:3},{lat:2,lng:3}...]
I want to make a different array whose elements will be a function and the variables of the function will be the elements from the JSON array, like so:
var coordinates = [
new google.maps.LatLng(1, 2),
new google.maps.LatLng(1, 3),
new google.maps.LatLng(2, 3),
....
];
I made a function using forEach that counts the elements of the JSON array (for learning and trying to find a way to what I want) but I cant think of a way make the array mentioned above.
You could use Array map method:
var coordinates = JSON_array.map(function(coordinate) {
return new google.maps.LatLng(coordinate.lat, coordinate.lng);
})
This method gives you an new array based on (1) the original array and (2) how you deal with each element. Here's more detailed doc for the method.
you can also use regular for loop
coordinates = [];
for(var i=0;i<JSON_array.length;i++){
coordinates.push(new google.maps.LatLng(JSON_array[i].lat,JSON_array[i].lng));
}
For mapping element from one array to another you can use Array.prototype.map function like
var JSON_array = [{lat:1,lng:2}, {lat:1,lng:3},{lat:2,lng:3}...];
var coordinates = JSON_array.map(function(el){ return new google.maps.LatLng(el.lat, el.lng)});
As Grundy commented you can just do:
coordinates = JSON_array.map(function(x) {
return new google.maps.LatLng(x.lat, x.lng);
});
You might want to get your nomenclature straight though, this has nothing to do with JSON.