Associative Array in Javascript Key is number, but access as string (Associative) - javascript

I'm attempting to create a lookup table in Javascript that is populated ahead of time by a table (basically just turning a table into a Javascript array), then, a dropdown value is referenced for the "score" column of the table.
var pointsGrid=[];
// First column is the primary key in a table with the same layou
// Second column is the name of the move
// Third column is the score
pointsGrid.push(['1',"Run",0.1]);
pointsGrid.push(['2',"Jump",0.5]);
pointsGrid.push(['3',"Twist",0.9]);
<select id="moveSelect">
<option value="1">Run</option>
<option value="2">Jump</option>
<option value="3">Twist</option>
</select>
My question is during the onChange event, when I read the value of the dropdown, how do I reference the array by string, instead of by number?
For example:
pointsGrid["1"] not pointsGrid[1], like in pointsGrid["StringKey"]? It keeps going back to pointsGrid[1] which is pulling the wrong score value.
Thank you in advance,
Dan Chase

Arrays number-indexed data structures. Use objects instead.
var pointsGridObj = {}
pointsGridObj["1"] = ["Run", "0.1"]
pointsGridObj["2"] = ["Jump", "0.5"]
pointsGridObj["3"] = ["Twist", "0.9"]
Or if you have the triples as an array,
pointsGridobj = {};
for(var i=0; i<pointsGrid.length; i++) {
pointsGridobj[pointsGrid[i][0]] = pointsGrid.slice(1,3);
}

Related

How to retrieve a random value from an array that has values separate by a new line

I am a complete newbie at JS and currently using it in a testing capacity along with the Karate framework to perform some UI testing. I am having the following problem:
There is a dropdown that has the following HTML:
<select class=id="CarId" name="CarId" aria-describedby="CarId-error" aria-invalid="false" xpath="1">
<option value="1">Mercedes</option>
<option value="2">BMW</option>
<option value="3">Lexus</option>
<option value="4">Honda</option>
<option value="5">Toyota</option>
<option value="6">VW</option>
</select>
I used the following Karate method to get all text values under the dropdown:
def grabValues = scriptAll('#CarId', '_.textContent')
Once printed, the array look like this:
[
"Mercedes\nBMW\nLexus\nHonda\nToyota\nVW\n"
]
console.log(Math.floor(Math.random() * (grabValues.length-1)))
When printed, it keeps giving me 0.0. I am assuming this is because the array contains new lines vs comma delimitated? If so, how can I get rid of the new lines and replace with commas?
What you want is to get the text from each <option>
def grabValues = scriptAll('#CarId option', '_.textContent')
This will give you an array of text values like
["Mercedes","BMW","Lexus","Honda","Toyota","VW"]
To get a random index you would use
Math.floor(Math.random() * grabValues.length)
One line code is console.log(myArr[0].split('\n'))
OR
Let's assume : The array of String is stored in myArr
let myArr = ["ABC\nDEF\nGHI\nJKL\nMNO\nPQR\nSTU\nVWX\nYZA\n"]
To get the string from the array
let stringOfArr = myArr[0]
Storing the new array from the stringOfArr deleminated by '\n' in newArray
let newArray = stringOfArr.split('\n')
console.log(newArray)

ng-repeats, showing record while it's value is a part of field of another object

I've got objects 'ing' with a field named 'id' and another one called 'fObj' with a field named 'contain'.
By using ng-repeat i'd like to show only these 'ing' objects where ing.id is a part of fObj.contain
e.g.
ing=[{id: 1,field: value},{id:2, field: othervalue},{id:3, field: cat}];
fObj={field1: value1, field: value2, contain: ':1:3:'};
By having this contain value I'd like to show only ing's with id=1 and id=3
Yeah, I know there are two types of data (number and string) but even if i changed numbers to strings it still didn't work
I just dont't know how to make it works. It's probably some kind of custom filter, but I've tried couples and nothing happend.
I would be glad if you suggest me a solution.
Thanks
In your controller,
var ids = fObj.contain.split(':');
// the array for your ng-repeat
var displayIng = [];
// loop the objects, see if the id exists in the list of id's
// retrieved from the split
for(i = 0; i < ing.length; i++) {
if(ids.indexOf(ing.id.toString()) displayIng.push(ing[i]);
}
I would split the numbers out of fObj.contain; and use them as hashmap object keys for simple filtering of the array
var ing=[{id: 1},{id:2},{id:3}];
var fObj={contain: ':1:3:'};
var IDs = fObj.contain.split(':').reduce(function(a,c){
a[c]=true;
return a;
},{});
// produces {1:true,3:true}
var filtered = ing.filter(function(item){
return IDs[item.id];
});
console.log(filtered)

JS and ExpressionEngine - Remove KV pairs by duplicate values only?

We're building a site with ExpressionEngine. We are running a SQL query to gather up all member IDs for a specific member group. After that, we are using EE tags to get data from a custom member field for each member ID.
The ID and field data need to stay paired, as we will be populating a drop-down so that the ID is the value and the field data is the text, so we are currently putting them into a JS array as key/value pairs. The call is as follows:
var array= [
{exp:query sql="SELECT * FROM exp_members WHERE group_id = 5"}
{exp:member:custom_profile_data
member_id="{member_id}"}
{if company != ''}
{{member_id}:"{company}"},
{/if}
{/exp:member:custom_profile_data}
{/exp:query}
};
This gives us the output:
var array = [
{1:"name01"},
{2:"name02"},
{3:"name01"},
{4:"name03"}
];
Now, our problem. We need to remove objects based on duplicate field data (values) only, so the above array would look like this:
var array = [
{1:"name01"},
{2:"name02"},
{4:"name03"}
];
None of these IDs (keys) will ever be the same, but the field data (values) can be. So we want to keep the first KV pair that comes through with a unique value, but remove any subsequent dupes of that value - despite the fact that they will not be true "duplicate values" due to a different ID (key).
Keeping in mind that the KV pairs are all dynamic, is there any possible way to do this via JS so we can create a new array for the cleaned data to pass to the drop-down?
You could handle the duplications by modifying your MySQL query. (In my example, my custom field ID was 1.)
var myArray = [];
{exp:query sql="SELECT MIN(m.member_id) AS co_member_id, d.m_field_id_1 AS company FROM exp_members m INNER JOIN exp_member_data d ON m.member_id = d.member_id WHERE d.m_field_id_1 != '' AND m.group_id > 0 GROUP BY d.m_field_id_1;"}
myArray.push({{co_member_id}: "{company}"});
{/exp:query}
This query would use the first (in the ordinal sense) member_id found; you could also change the MIN to MAX and get the last.
This will give you a clean output in your source, without the need for any additional JS processing. I'd also recommend changing the names of the variables you're outputting as to not conflict in EE's parsing.
I would do it like...
function removeDups(arry){
var tmp = {}, retainIdx=[], newArry=[];
arry.forEach(function(obj, idx){
var val = obj[Object.keys(obj)[0]];
if(val && !tmp[val]){
retainIdx.push(idx);
tmp[val] = true;
}
});
retainIdx.forEach(function(i){
newArry.push(arry[i]);
});
return newArry;
};

How can I retrive a value from this json object?

<script>
var output = {"regions":{"4441":"Avtonomna Respublika Krym","4431":"Cherkas'ka Oblast'","4432":"Chernihivs'ka Oblast'","4433":"Chernivets'ka Oblast'","4434":"Dnipropetrovs'ka Oblast'","4435":"Donets'ka Oblast'","4436":"Ivano-Frankivs'ka Oblast'","4437":"Kharkivs'ka Oblast'","4438":"Khersons'ka Oblast'","4439":"Khmel'nyts'ka Oblast'","4440":"Kirovohrads'ka Oblast'","4443":"Kyyivs'ka Oblast'","4445":"L'vivs'ka Oblast'","4444":"Luhans'ka Oblast'","4442":"Misto Kyyiv","4450":"Misto Sevastopol","4446":"Mykolayivs'ka Oblast'","4447":"Odes'ka Oblast","4448":"Poltavs'ka Oblast'","4449":"Rivnens'ka Oblast'","4451":"Sums'ka Oblast'","4452":"Ternopil's'ka Oblast'","788":"Ukraine","4453":"Vinnyts'ka Oblast'","4454":"Volyns'ka Oblast'","4455":"Zakarpats'ka Oblast'","4456":"Zaporiz'ka Oblast'","4457":"Zhytomyrs'ka Oblast'"}}
alert(output.regions[1]);
</script>
This part gives me undefined:
alert(output.regions[1]);
How can I grab the first key/value pair for example. Basically I need to turn this into a select dropdown, the numeric keys would be the values and the names of the cities would be the option text.
Can iterate over it like:
for(key in output.regions) {
alert(key +' => '+output.regions[key]); // 4441 => Avtonomna Respublika Krym ...etc
}
Rather than a numeric index, you'll want to key into regions with the keys you've specified, like 4441, 4431, etc:
var output = {"regions":{"4441":"Avtonomna Respublika Krym","4431":"Cherkas'ka Oblast'","4432":"Chernihivs'ka Oblast'","4433":"Chernivets'ka Oblast'","4434":"Dnipropetrovs'ka Oblast'","4435":"Donets'ka Oblast'","4436":"Ivano-Frankivs'ka Oblast'","4437":"Kharkivs'ka Oblast'","4438":"Khersons'ka Oblast'","4439":"Khmel'nyts'ka Oblast'","4440":"Kirovohrads'ka Oblast'","4443":"Kyyivs'ka Oblast'","4445":"L'vivs'ka Oblast'","4444":"Luhans'ka Oblast'","4442":"Misto Kyyiv","4450":"Misto Sevastopol","4446":"Mykolayivs'ka Oblast'","4447":"Odes'ka Oblast","4448":"Poltavs'ka Oblast'","4449":"Rivnens'ka Oblast'","4451":"Sums'ka Oblast'","4452":"Ternopil's'ka Oblast'","788":"Ukraine","4453":"Vinnyts'ka Oblast'","4454":"Volyns'ka Oblast'","4455":"Zakarpats'ka Oblast'","4456":"Zaporiz'ka Oblast'","4457":"Zhytomyrs'ka Oblast'"}}
alert(output.regions[4441]); // alerts "Avtonomna Respublika Krym"
The regions entity is an object and not an array so you have to select its attribute by its associated key.
output.regions.4441
or
output.regions['4441']
The value with the key "regions" is a map, not an array - it has no ordering, therefore there is no concept of "first key/value pair" - you'll have to impose your own ordering if you want one.
This is because output.regions is an object, not an array. You would either need to access by the ID (778) or if you don't know it, than you can iterate to find it.
for (k in output.regions) { var key = k; break; }
alert(output.regions[key]);
There is no "first" value. Properties of javascript objects are not ordered. You can iterate over a javascript object like this:
for(key in output.regions){
alert(output.regions[key])
}
and check for the cycle of iteration, but there's no guarantee that the order won't change unexpectedly. To have a guaranteed order, you need to use an array.

How to get the id value of a multiple SELECTION using javaScript?

I want to get the ID values of multiple selection list. The multiple selection list
is generated dynamically. How to get that values? If i can able to get the values means,
can I convert it to JSON object or, it ll be obtained as JSON object!!!!
Here is my code to generate it dynamically.
function displayMultipleList() {
EmployeeManagement.getResponseList(function (respList) {
var respOptionsSelect = document.getElementById('respOptions');
var searchOptions = null;
for (var i = 0; i < respList.length; i++) {
var resp = respList[i];
selectOptions = document.createElement('option');
selectOptions.value = resp.respID;
selectOptions.innerHTML = resp.respName;
respOptionsSelect.appendChild(selectOptions);
}
});
}
Thanks.
You can use the serializeArray() function:
$("#respOptions").serializeArray()
It will return to you the selected objects in a JavaScript array which can be easily stringified to a JSON string.
If your <select> element looks like this (don't forget the name attribute, as serializeArray needs it!):
<select name="respOptions" id="respOptions" multiple="true">
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>
If items 2 and 3 were selected, you would get this back from the function:
[{ name: "respOptions", value: "2"}, {name: "respOptions", value: "3"}]
EDIT - I forgot to add the name attribute to the <select> element. Sorry for the confusion.
Taking the ambiguity of the question as a challenge, here are two options.
You're asking "how to get the values" and "convert it to JSON object." Taking that literally, and ignoring the mention of id, you can simply do this:
var x = JSON.stringify( $('#respOptions').val() );
...which will give you a simple (JSON) array of the selected values:
["somevalue","anothervalue"]
But if by "get the ID values" you mean "get the IDs and values of selected options", then you can do something like this:
var y = $('#respOptions option:selected').map( function(i,el){
var result = {};
result[ el.id ] = $(el).val();
return result;
}).get();
y = JSON.stringify(y);
...which will give you an array like this:
[{"id1":"somevalue"},{"id5":"anothervalue"}]
I threw together a fiddle that makes assumptions about your HTML, and mocks in the respList from which the options are dynamically added. It solves the problem both ways.
If your browser doesn't support JSON.stringify, you can use Crockford's oft-recommended json2.js library.
Here's how you iterate over a list of options inside a select element and get the ids:
http://jsfiddle.net/bXUhv/
In short:
$('option', $('#optionlist')).each(function() {
alert($(this).attr('id'));
});​
With regard to converting any data into a JSON object, please look into this jQuery library.
Multiple select and If you want the id in a array format
fiddle Example here
var countries = [];
$.each($(".country option:selected"), function() {
countries.push($(this).attr("id"));
});
alert(countries.join(", "));

Categories

Resources