Get the first value from a nested object - javascript

I have an object called allInvalidFields which lists invalid fields under an identifier e.g _0 or _3
The object could look like this
allInvalidFields = {
"_0" : {
0: input.foo,
1: select.la
}
"_1" : {
0: input.foofoo,
1: select.lala
}
}
But equally it could not have _0 as the first key and could look like this:
allInvalidFields = {
"_1" : {
0: input.alice,
1: select.bob
}
"_3" : {
0: input.foo
}
}
How can I get the first value from the first object in the list? So in the example above it would be input.foo or input.alice depending on which dataset was being searched.

Inferred that the keys are in numeric order and prepended with "_".
Under these assumptions :
function first(obj,n){
let smallest = Infinity;
for(i in obj){
console.log(i);
let val='';
if (i.toString()[0]=='_'){
val = parseInt(i.toString().substring(1));
}else{
val = i;
}
if( val < smallest ){
smallest = val;
}
}
if(n>0){
return first(obj["_"+smallest],n-1);
}
return obj[smallest];
}
first({"_0" : {
0: "input.foo",
1: "select.la"
},
"_1" : {
0: "input.foofoo",
1: "select.lala"
}},1); // input.foo

You need something like this.
var allInvalidFields = {
"_0": {
"0": "input.foo",
"1": "select.la"
},
"_1": {
"0": "input.foofoo",
"1": "select.lala"
}
};
var firstInput = Object.keys(allInvalidFields)[0];
console.log(allInvalidFields[firstInput][0]);

Object.values(allInvalidFields)[0][0];
take the first value of the first property object.
Small note: having such keys like _1 is bad style...
Short version of programaths answer:
allInvalidFields["_"+Object.keys(allInvalidFields).map(el=>el=+el.replace("_","")).sort()[0]][0]

Related

To check the two array of object values based on the respective key?

I am trying to compare two array of object values based on the specific key. Two object has same keys based on that i have to check whether the values are equal or not. One array is actual JSON object and the second one is test data, we have to verify the test data with JSON object and moreover if the test data value is same, it might have some extra space we need to trim that value as well.
var actualObject= [
{
"q1": "componentWillMount"
},
{
"q2": "willComponentUpdate"
},
{
"q3": "setState"
},
{
"q4": "componentUpdated"
}
]
Var testData =[
{q1: "componentWillMount"},
{q2: "willComponentUpdate"},
{q3: " PropTypes"},
{q4: "componentDidMount"}]
I will get the testData values from the Html code, on selection of radio buttons. Now i need to check how many answer are correct with actual JSON.
JS Code for it:
var marks= 0;
var wrong = 0;
for(var k =0 ; k<actualObject.length;k++){
if(JSON.stringify(actualObject[k]) == JSON.stringify(testData[k])){
marks++;
}
else {
wrong++;
}
}
var actualObject = [{
"q1": "componentWillMount"
},
{
"q2": "willComponentUpdate"
},
{
"q3": "setState"
},
{
"q4": "componentUpdated"
}
]
var testData = [{
q1: "componentWillMount"
},
{
q2: "willComponentUpdate"
},
{
q3: " PropTypes"
},
{
q4: "componentDidMount"
}
];
var marks = 0;
var wrong = 0;
for (var k = 0; k < actualObject.length; k++) {
if (JSON.stringify(actualObject[k]) == JSON.stringify(testData[k])) {
marks++;
} else {
wrong++;
}
}
console.log(marks, wrong);
Actually i would like to take value from each key and compare it with the actualObject.
If I understand correctly something like this should work:
Object.entries(testData).forEach(function (entry) {
if (actualObject[entry[0]] === entry[1].trim()) {
//answers match
} else {
//answers don't match
}
});
If you need to compare regardless of case then change entry[1].trim() to entry[1].trim().toLowerCase().
EDIT:
Just to remind you that maybe you should add a check whether or not the values in the test data are null/undefined, if they are strings or not, etc.

How to print JSON file Using Java Script

var user_business_data =[
{
"user_id":"5db3e3b1",
"blog":{
"blog_id":"128c522e"
},
"business_units":[
{
"business_unit_id":"000396c9",
"viewing":101
},
{
"business_unit_id":"01821e44",
"viewing":102
},
{
"business_unit_id":"02cbcad5",
"viewing":103
}
]
}
]
I want to get all the "business_unit_id" and store in a varible. for this i need get all the "business_unit_id". so i tried to print all the id's with the below code but i was unable to print.
if (undefined !== user_business_data.business_units && user_business_data.business_units.length) {
for(var i=0;i<user_business_data.business_units.length;i++){
var key = user_business_data.business_units[i];
console.log("Key : "+key, "Values : "+user_business_data.business_units[key]);
}
} else {
console.log("Undefined value");
}
There always i am getting undefined value.
var user_business_data=[{"user_id":"5db3e3b1","blog":{"blog_id":"128c522e"},"business_units":[{"business_unit_id":"000396c9","viewing":101},{"business_unit_id":"01821e44","viewing":102},{"business_unit_id":"02cbcad5","viewing":103}]}]
var unit_ids = [];
user_business_data.forEach(function(user) {
user.business_units.forEach(function(business) {
unit_ids.push(business.business_unit_id);
});
});
console.log(unit_ids);
user_business_data is an array, not an object, so you either need to loop through it or read a specific index from it.
Also, key in your code will be an object (a single business unit object), so you can't print it directly - instead you need to fetch a specific property within the object.
Here's a simple demo reading the first key from the outer array and then listing all the specific properties from the business units. The code can be simplified further potentially, but this illustrates the point:
var user_business_data =
[{
"user_id": "5db3e3b1",
"blog": {
"blog_id": "128c522e"
},
"business_units": [{
"business_unit_id": "000396c9",
"viewing": 101
},
{
"business_unit_id": "01821e44",
"viewing": 102
},
{
"business_unit_id": "02cbcad5",
"viewing": 103
}
]
}]
if (undefined !== user_business_data[0].business_units && user_business_data[0].business_units.length) {
for (var i = 0; i < user_business_data[0].business_units.length; i++) {
var key = user_business_data[0].business_units[i].business_unit_id;
console.log("Key : " + key, "Values : " + user_business_data[0].business_units[i].viewing);
}
} else {
console.log("Undefined value");
}
I suggest you get clear in your head the difference between arrays, objects and properties in JSON / JS objects, and then this kind of thing will become trivial.
user_business_data is an array and not an object.If you want to access any object from an array you have to specify the index as of which position you are referring.Therefore in your example change it to following to work:
if (undefined !== user_business_data[0].business_units && user_business_data[0].business_units.length) {
for(var i=0;i<user_business_data[0].business_units.length;i++){
var key = user_business_data[0].business_units[i]. business_unit_id;
console.log("Key : "+key, "Values : "+user_business_data[0].business_units[key]);
}
} else {
console.log("Undefined value");
}
It's because user_business_data is an array, not an object yet you access it like user_business_data.business_units instead of user_business_data[0].business_units
var user_business_data = [{"user_id": "5db3e3b1","blog": {"blog_id": "128c522e"}, "business_units": [{"business_unit_id": "000396c9","viewing": 101}, {"business_unit_id": "01821e44","viewing": 102},{"business_unit_id": "02cbcad5","viewing": 103}]}];
// Both methods give the same result, but the second checks for null values.
var ids1 = user_business_data[0].business_units.map(x => x.business_unit_id)
console.log('Method 1:', ids1);
// The && check for null values, kinda like an if statement.
var data = user_business_data.length && user_business_data[0]
var units = data && data.business_units
var ids2 = units && units.length && units.map(x => x.business_unit_id)
console.log('Method 2:', ids2)
If you want to print only the business_unit_ids then you can do as follows:
var user_business_data =
[
{
"user_id": "5db3e3b1",
"blog": {
"blog_id": "128c522e"
},
"business_units": [
{
"business_unit_id": "000396c9",
"viewing": 101
},
{
"business_unit_id": "01821e44",
"viewing": 102
},
{
"business_unit_id": "02cbcad5",
"viewing": 103
}
]
}
]
for(var i=0;i<user_business_data[0]["business_units"].length;i++){
console.log(user_business_data[0]["business_units"][i].business_unit_id)
}

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);
}
}

Arrays in javascript with jquery

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" }
]

Look for a value for a given key in JSON and change the value using javascript

I am looking to write a function which can look up a value based on a key and replace that value with another. The key is a tree from the start node of JSON. Here is the example.
var myData = {
name : 'Dan',
address: {
city : 'Santa Clara',
details : {
'prevhouse' : ''
}
}
}
Input to the function is a key tree. For eg, myData-address-details-prevhouse
When I pass this key with a new value, say 'Texas', the prevhouse value will get changed to the new value I am sending.
and new JSON will be
var myData = {
name : 'Dan',
address: {
city : 'Santa Clara',
details : {
'prevhouse' : 'Texas'
}
}
}
Here is what I wrote so far
var tree = key.split("-");
now the tree variable contains ["myData","address", "details","prevhouse"]
I know that we can access the object using myData[tree[0]][tree[1]][tree[2]], but somehow not able to get it dynamic from parsed value.
how do we generate this dynamically since the length of the depth is not known till runtime.
Hope to get a help.
try with this code:
var myData = {
name: 'Dan',
address: {
city: 'Santa Clara',
details: {
prevhouse: ''
}
}
};
function setAttribute(obj, key, value) {
var i = 1,
attrs = key.split('-'),
max = attrs.length - 1;
for (; i < max; i++) {
attr = attrs[i];
obj = obj[attr];
}
obj[attrs[max]] = value;
console.log('myData=', myData);
}
setAttribute(myData, "myData-address-details-prevhouse", "Texas");
here a working jsfiddle demo; see the console for the result
You should be able to iterate through each key because your JSON is just a JS object. So go through each key, check if it's defined, if it is, use that object for your next check. That'll get you where you want to go. Keep in mind you'll be setting the last key to your value.
basic psuedo-code without dealing with setting:
obj = data;
for (key in keys) {
obj = obj[key]
}
Something like this would do:
function update(node, path, value) {
path = path.split('-');
do {
node = node[path.splice(0, 1)];
} while(path.length > 1);
node[path[0]] = value;
}
Given that myData is the object, I think you should be using myData[tree[1]][tree[2]][tree[3]] and throwing away the first item in the array.
Something like this should work recursively (untested)
function updateValue(obj, key, value)
{
var keys = key.split('-');
updateObjectValue(obj, keys.shift(), value);
}
function updateObjectValue(obj, keyArray, value)
{
if (keyArray.length == 1) {
obj[keyArray[0]] = value;
}
else if (keyArray.length > 1) {
updateObject(obj[keyArray[0]], keyArray.shift(), value);
}
}

Categories