Arrays in javascript with jquery - javascript

I want to create an array with would hold all option element values and html text. And in a result I would like something like this:
console.log( myArray );
output:
[ "htmlText" : '0', "htmlText2" : '1', ... ]
if this is possible, how can I access them and get their keys?
or at least 2dim array
How Can I do that?
this is what I have now:
function optionValues( selectEl )
{
var values = [];
if ( selectEl.length )
{
$(selectEl).find('option').each( function(){
values.push( $(this).val() );
});
return values;
}
else
return false;
}
function optionHtmls( selectEl )
{
var html = [];
if ( selectEl.length )
{
$(selectEl).find('option').each( function(){
html.push( $(this).html() );
});
return html;
}
else
return false;
}

The function can be simplified:
function optionValues(selectEl) {
var options = {};
$(selectEl).find('option').each(function() {
options[this.label] = this.value;
});
return options;
}
console.log(optionValues('select')) // {Text 1: "1", Text 2: "2", Text 3: "3"}
Demo: http://jsfiddle.net/c5e3vemo/

Use {} instead of [] to make an associative array.
var values = {
htmlText: 0,
htmlText2: 1,
};
console.log(values['htmlText']);
To append things to an associative array (also referred to as an object):
values['stuff'] = 'foo';
values['thing'] = 'bar';
To loop over this:
for (var key in values) {
/* check to make sure it's actually a valid key */
if (values.hasOwnProperty(key)) {
console.log(key + " => " + values[key]);
}
}

An object would suit your needs best in this case. You can use map() to create one from the option elements in any given select. Try this:
var values = $('#mySelect option').map(function() {
var obj = {};
obj[$(this).text()] = $(this).val();
return obj;
});
Example fiddle
Given this HTML:
<select id="mySelect">
<option value="1">Foo</option>
<option value="2">Bar</option>
</select>
The returned object would look like this:
[
{ "Foo": "1" },
{ "Bar": "2" }
]

Related

Why filter function does not return correct value in Javascript

I am new to Javascript and hence the below error might be from a novice.
I have the below complex object and depending on the value of first array, I would like to populate a select options from "Array of Objects".
The Values returned from filter function is not what I expect, so I request your assistance.
var complexObject = {
itemList: ["Item1", "Item1", "Item1", "Item1", "Item2", "Item2"],
itemDetails: [{
itemList: "List1",
itemType: "Type1"
},
{
itemList: "List2",
itemType: "Type2"
},
{
itemList: "List3",
itemType: "Type3"
},
{
itemList: "List4",
itemType: "Type4"
},
{
itemList: "ListH",
itemType: "TypeH",
},
{
itemList: "ListZ",
itemType: "TypeZ",
}
]
};
function populateItems() {
var itemListArray = complexObject.itemList.slice();
var itemCount = itemListArray.length;
var i = 0;
while (i < itemCount) {
if (itemListArray[i] == itemListArray[i + 1]) {
itemListArray.splice(i, 1);
} else
i++;
itemCount = itemListArray.length;
}
var option1List = document.getElementById("option1");
for (i = 0; i < itemListArray.length; i++) {
var newOption = new Option(itemListArray[i]);
option1List.add(newOption);
}
}
function changeOption2() {
var selectedOption = document.getElementById("option1").value;
var selectedType = complexObject.itemList.filter(function(value, index) {
if (value == selectedOption)
return (complexObject.itemDetails[index].itemType);
});
var option2List = document.getElementById("option2");
var i = 1;
while (i < option2List.length)
option2List.remove(i);
option2List = document.getElementById("option2");
for (i = 0; i < selectedType.length; i++) {
var newOption = new Option(selectedType[i]);
option2List.add(newOption);
}
}
<body onload="populateItems()">
<p>Option 1:</p>
<select id="option1" onchange="changeOption2()">
<option>Select</option>
</select>
<br><br>
<p>Option2:</p>
<select id="option2">
<option>Select</option>
</select>
<body>
Thanks for your time and patience.
From what I understand the filter function takes a test, and then returns all the elements that pass the test. (docs) so your code would not return the item type, but rather the selected item from item list. You probably want to do something more like this
var selectedType = complexObject.
itemDetails[complexObject.itemList.findIndex(elm => elm == selectedOption)];
(findIndex docs)
Alternatively you could use the reduce function, but that would return and array around the selected item type, and it looks like you mainly want to do a lookup operation. You may even want to consider converting itemDetails into an object structured like this
{
"Item1": {
itemList: "List1",
itemType: "Type1"
}
}
That way you could find the type by just checking
return complexObject.itemDetails[selectedOption].itemType
You want objects from "itemDetails" array but you are filtering "itemList",in JavaScript filter function just return object from the same array that's why you see the result ("Item1", "Item1", "Item1", "Item1") instead of ("Type1", "Type2", "Type3", "Type4"), my advice is that you use a generic for loop like this:
var selectedType=[];
for(var i=0;i<complexObject.itemList.length;i++){
var value = complexObject.itemList[i];
if (value == selectedOption){
selectedType.push(complexObject.itemDetails[i].itemType);
}
}
See filter docs.
You must return a boolean value inside your filter callback. It will filter out elements of the array if the function returns false and keep it if it returns true. Since you are not returning a boolean value but a string, it will return true since javascript sees a non-null or non-undefined value as true.
You might want to use Array.reduce() instead.
try this:
var selectedType=complexObject.itemList.reduce(function(accumulator, value, index) {
if (value==selectedOption) accumulator.push(complexObject.itemDetails[index].itemType);
return accumulator;
}
, []);

Extract values from JSON

I have the below JSON string. The id-dashes in the file are not optional unfortunately, neither is the syntax. I would like to extract the "dd" values with JavaScript/Node.
{
"a-id":{
"b-id":"random",
"bb-id":"random",
"bbb-id":"random",
"bbbb-id":{
"c":[
{
"d":"random",
"dd":"This_info_is_needed"
},
{
"d":"random",
"dd":"This_info_is_needed"
},
{
"d":"random",
"dd":"This_info_is_needed"
},
{
"d":"random",
"dd":"This_info_is_needed_2"
}
]
},
"bbbbb-id":"random",
"bbbbbb-id":"random"
}
}
I would be open to use any additional helper like lodash, jQuery, etc.
The output should be an array with: This_info_is_needed and This_info_is_needed_2.
Thank you in advance.
You can create custom function that will search your data deep and return value if key is dd using for...in loop.
var obj = {"a-id":{"b-id":"random","bb-id":"random","bbb-id":"random","bbbb-id":{"c":[{"d":"random","dd":"This_info_is_needed"},{"d":"random","dd":"This_info_is_needed"},{"d":"random","dd":"This_info_is_needed"},{"d":"random","dd":"This_info_is_needed"}]},"bbbbb-id":"random","bbbbbb-id":"random"}}
function getDD(data) {
var result = []
for(var i in data) {
if(i == 'dd') result.push(data[i])
if(typeof data[i] == 'object') result.push(...getDD(data[i]))
}
return result
}
console.log(getDD(obj))
If you just interested in the values only, can also just do this:
var obj = {"a-id":{"b-id":"random","bb-id":"random","bbb-id":"random","bbbb-id":{"c":[{"d":"random","dd":"This_info_is_needed"},{"d":"random","dd":"This_info_is_needed"},{"d":"random","dd":"This_info_is_needed"},{"d":"random","dd":"This_info_is_needed"}]},"bbbbb-id":"random","bbbbbb-id":"random"}};
var desiredResults = obj['a-id']['bbbb-id']['c'].map(function(data){return data.dd});
console.log(desiredResults);

How to save distinct values in an object in javascript?

I have a bunch of log data which is stored in a variable. Each log value contains a camera name and system ip. I want to create an object which has names as all the distinct system ip's and corresponding value as an array which contains all the camera names corresponding to that system ip. Below is my code ---
$http(req).success(function(data){
$scope.logs = data;
$scope.cameras={};
var v =$scope.logs[0].systemIp;
$scope.cameras["v"]=[];
$scope.cameras["v"].push($scope.logs[0].cameraName);
for(i=1;i<$scope.logs.length;i++){
v=$scope.logs[i].systemIp;
var flag=0;
for(j in $scope.cameras){
if(j==="v")
{
flag=1;
break;
}
}
if(flag==0)
{
$scope.cameras["j"]=[];
$scope.cameras["j"].push($scope.logs[i].cameraName);
}
else if(flag==1)
{
$scope.cameras["v"].push($scope.logs[i].cameraName);
}
}});
And this is what my data looks like --
[{
"_id": "57683fd82c77bb5a1a49a2aa",
"cameraIp": "192.16.0.9",
"cameraName": "garage2",
"systemIp": "192.168.0.2"
},
{
"_id": "57683f8e2c77bb5a1a49a2a9",
"cameraIp": "192.16.0.8",
"cameraName": "garage1",
"systemIp": "192.168.0.2"
},
{
"_id": "57683f5e2c77bb5a1a49a2a8",
"cameraIp": "192.16.0.7",
"cameraName": "Back Door",
"systemIp": "192.168.0.4"
}]
When I print $scope.cameras on my console it gives this as the output -
Object { v: Array[3] }
I want by cameras object to look like this --
{ "192.168.0.2" : [ "garage1" , "garage2"] ,
"192.168.0.4" : [ "Back Door"] }
I am new to javascript, any help is appreciated.
If you are using the Lodash or Underscore library (which I highly recommend), you can just use the _.groupBy() function to do what you are after (along with some other functions to ensure all values are unique).
However, you can also easily implement it yourself:
function groupByDistinct(arr, prop, mapFn) {
mapFn = mapFn || function (x) { return x; };
var output = {};
arr.forEach(function (item) {
var key = item[prop],
val = mapFn(item);
if (!output[key]) {
output[key] = [val];
return;
}
if (output[key].indexOf(val) < 0) {
output[key].push(val);
}
});
return output;
}
Use it for your code like so:
$scope.cameras = groupByDistinct(data, 'cameraIp', function (logEntry) {
return logEntry.cameraName;
});
You are passing a string such as "v" or "j" as your object key, and this string are actually ending being your object key and not the value of this variables as you want. You can use something like this:
for(i=0; i < $scope.logs.length; i++){
var _sysIp = $scope.logs[i].systemIp,
_camName = $scope.logs[i].cameraName;
if(!$scope.cameras.hasOwnProperty(_sysIp)) {
$scope.cameras[_sysIp] = [_camName];
} else if ($scope.cameras[_sysIp].indexOf(_camName) < 0) {
$scope.cameras[_sysIp].push(_camName);
}
}

Json Filtering in jquery

Hello i want to filter json data like sql query without the help of plugins like alasql.js or linq.js or any plugins.
for example
{
"Managing PCL": [
{
"idItScreen": "1436",
"topicName": "Managing PCL",
"isFav": 0,
"cdeItScreen": "ListActiveTarif",
"busScreenName": "My Current Tarif"
},
{
"idItScreen": "1437",
"topicName": "Managing PCL",
"isFav": 0,
"cdeItScreen": "ListTermineTarif",
"busScreenName": "History Tarif"
}
]
}
for example i need to get data where idItScreen>1430 so that json data must be displayed the main challenge is to do without plugins so please reccomend me a good solution to do this without plugins
First turn your JSON into a Javascript object:
var obj = JSON.parse(myJSON);
Then do your filtering:
var matches = [];
var arr = obj['Managing PCL'];
for (var i = 0; i < arr.length; i++) {
if (arr[i].idItScreen > 1430) {
matches.push(arr[i]);
}
}
Or using jQuery.grep:
var matches = jQuery.grep(obj['Managing PCL'], function(n, i) {
return n.idItScreen > 1430;
});
Now matches contains the matching items.
If you want to get the JSON again, just use JSON.stringify:
var filteredJSON = JSON.stringify({'Managing PCL': matches});
You can also simply use .filter:
var matches = [];
var all = obj['Managing PCL'];
var filtered = all.filter(function(){
return $(this).idItScreen > 1430;
})
You don't need to use jQuery for this. You can use the filter() method of Array.prototype. See the working snippet below:
var obj = {
"Managing PCL": [{
"idItScreen": "1436",
"topicName": "Managing PCL",
"isFav": 0,
"cdeItScreen": "ListActiveTarif",
"busScreenName": "My Current Tarif"
}, {
"idItScreen": "1437",
"topicName": "Managing PCL",
"isFav": 0,
"cdeItScreen": "ListTermineTarif",
"busScreenName": "History Tarif"
}]
};
var filteredArray = obj['Managing PCL'].filter(function(item) {
return item.idItScreen > 1430;
});
obj['Managing PCL'] = filteredArray;
document.getElementById('result').innerHTML = JSON.stringify(obj);
<div id="result"></div>
You don't need jQuery for this. Use filter on the data instead.
function filterData(data, key, value) {
return data.filter(function (el) {
return el[key] > value;
});
}
// Note, `filter` operates on arrays, so you need to specify the
// array that contains the data
var result = filterData(data['Managing PCL'], 'idItScreen', '1430');
Also note that filter returns a new array containing the objects that it's found that match your criteria. You can access those objects in the usual way: result[0], for example.
DEMO
You could even expand this to create a function that returns data based on the operator too, not just greater-than, by using a look-up object:
var lookup = {
'>': function (data, value) { return data > value; },
'<': function (data, value) { return data < value; },
'===': function (data, value) { return data === value; }
}
function filterData(data, key, operator, value) {
return data.filter(function (el) {
return lookup[operator](el[key], value);
});
}
filterData(data['Managing PCL'], 'idItScreen', '>', '1430');
filterData(data['Managing PCL'], 'idItScreen', '===', '1430');
DEMO

How to Iterate over a hash in mustache.js

Given this hash
a = {
foo : { ... },
bar : { ... },
zap : { ... }
}
i want to iterate over it but since the keys are different I am not sure how to in Mustache.js
the output will look something like this foo : (contents here)
If you know the key in the nested object that you're trying to retrieve, you can use a function.
see: http://jsfiddle.net/jimschubert/zPWDJ/
js:
$(function() {
var names = {
"a": [
{"foo": { "name": "foo name"}},
{"bar": { "name": "bar name"}},
{"zap": { "name": "zap name"}}
],
"n": function() {
var self = this;
var n = "";
Object.keys(self).forEach(function(k, v) {
if (typeof self[k] == "object") {
if(!n) n = self[k]["name"];
}
});
return n;
}
};
var template = $('#template').html();
var out = $('#output');
var html = Mustache.to_html(template, names);
console.log(html);
out.html(html);
});​
html:
<script id="template" class="template" type="text/x-mustache">
{{#a}}
<p>{{n}}</p>
{{/a}}
</script>
<h1>Output</h1>
<div id="output">
</div>
​
This of course assumes your data is an array of objects (the a in your post would be one key of a greater array, maybe?) If you don't have an array, I don't see why you wouldn't be able to adjust this for an object and make a getter function for whatever properties of each key you're looking for.

Categories