Split a JSON array into JS variables - Bixby - javascript

So I have a API outputting JSON to my JS code (http://api.opentripmap.com/0.1/ru/places/bbox?lon_min=-123.049641&lat_min=37.550392&lon_max=-122.049641&lat_max=38.550392&kinds=foods&format=geojson&apikey=5ae2e3f221c38a28845f05b685eac8210f10fb196793a9d4f6653c25).
However it contains a JSON Array that looks like this- "coordinates": [ -122.510216, 37.769474 ]
Is there a way to split it into separate JS variables like one variable for the left side and another for the right side. At the moment the array is causing my code to crash as it can only accept one input in each slot.
Sorry If this is a simple question, I haven't been able to solve this yet...
EDIT:
Sorry for the terrible question layout. I have tried to splice and splitting the array with no success (splicing lead to a whole load of undefined errors).
My current code is
module.exports.function = function findLunch(myLocation) {
var loc_long_max = Number(myLocation.longitude) //grab longitude from user
var loc_lat_min = Number(myLocation.latitude) //grab latitude from User
var loc_long_min = loc_long_max - 0.5;
var loc_lat_max = loc_lat_min + 0.5;
var url_all = "http://api.opentripmap.com/0.1/ru/places/bbox?lon_min=" + loc_long_min + "&lat_min=" + loc_lat_min + "&lon_max=" + loc_long_max + "&lat_max=" + loc_lat_max + "&kinds=foods&format=geojson&apikey=5ae2e3f221c38a28845f05b685eac8210f10fb196793a9d4f6653c25"
var results = http.getUrl(url_all, { format: 'json' }); //gets json info from url_all.
console.log(results.features[rand].properties.name)
//console.log(results.feautres[rand].properties.rate)
console.log(results.features[rand].geometry.coordinates)
//console.log(results);
for (var i = rand; i < results.features.length; i++) {
console.log(results.features[rand].properties.name)
console.log(results.features[rand].properties.rate)
var businesses = {
name: results.features[rand].properties.name,
rating:results.features[rand].properties.rate,
coordinates: results.features[rand].geometry.coordinates
}
}
return businesses
So the coordinates need to be split and then be in the businesses var which is then outputted to Bixby....
EDIT 2 : Fixed it - thanks everyone for the help!
Thanks!

Not sure if this is smth you're asking but you can use destructuting assignment to assign items in an array to variables:
const coordinates = [ -122.510216, 37.769474 ];
const [coordinateOne, coordinateTwo] = coordinates;
console.log(coordinateOne) // -122.510216
console.log(coordinateTwo) // 37.769474

You can use destructuring to assign the first and second elements of the array to variables in a simple way:
const coordinates = [-122.510216, 37.769474];
const [left, right] = coordinates;
console.log(left);
console.log(right);

Related

I'm making a level maker with a preview from the code generated by the level maker, how could I do this?

I have made a Level Generator. Basically there is a 3 by 20 grid of squares, and you can select either one and depending on what you select when you click the button to generate it generate some code for you into a variable (string). It works perfectly but how am I going about to then get that generated code and turn it into a preview.
So far I found out using the keyword eval() but this only does the last line? Any ideas?
Here is a picture of what the layout is:
The Website So Far
The code that I originally had to detect the code was:
if (container.childNodes[index].innerText == 'pos3') {
if (container.childNodes[index].id == '1 second') {
text = text + '\n' + 'cube1 = new theCubeCreator(pos3, 0, 2, 1000),'
//amtselected = amtselected + 1
}....
Something like that then I would bundle it all up with this
var pos1 = 125 //middle
var pos2 = 70 //left
var pos3 = 180 //right
text = text + '\n' + 'cube1 = new theCubeCreator(pos2, 0, 2, 1000)' // Must add this to make it a end
var evaluation = eval(text)
console.log(evaluation);
Sorry if this is hard to read or if you want me to send examples.
What you are doing is bad practice. You should make an object that holds the functions and a generator function that converts and object into a function.
// object for the function / class you want to run
var data = {
name: "console.log",
isClass: false,
params: ["pos2", 0, 2, 1000],
};
var domParse = {
name: "DOMParser",
isClass: true,
params: ["<div>Hello World</div>", "text/html"],
};
var funcs = {
DOMParser: (args) => {
const dom = new DOMParser();
return dom.parseFromString(...args);
},
"console.log": (args) => console.log(...args),
};
// function to generate a function from the object.
function generate({ name, isClass, params }) {
return funcs[name](params);
}
generate(data); // console.log's pos2 0 2 1000
generate(domParse); // creates a DOM object
I took another way than doing eval() (well i still used eval). What I was doing was, to have a variable let text = '' then adding onto that variable doing something like this text = text + \n + '...'
Already this is bad so i took a different approach. all i changed was instead of having a string variable i would have a Array to store my code. Declearing it like this let text = [] then using push() to add the code to it, like so text.push(eval(...)).
Thats what i did to complete to fix my problem if you have any other way or eisier to follow (and yes i know this is messy) then comment (:

Create 2D Array out of another Array which is casted against an API

I'm working on a project using the opengeodata and some company-internal APIs. Therefore the code I'm using here is slightly changed.
First I'm using the Opencagedata Javascript API to get the lat/lng-Coordinates out of an address.
<script>
function geocode(query) {
$.ajax({
url: 'https://api.opencagedata.com/geocode/v1/json',
method: 'GET',
data: {
'key': 'MyKey',
'q': query,
'no_annotations': 1
},
dataType: 'json',
statusCode: {
200: function(response){ // success
var lat = response.results[0]['geometry']['lat'];
var lng = response.results[0]['geometry']['lng'];
$('#geo_result').text(lat + ' , ' + lng);
After that I'm using another internal API to get some information about places surrounding this location. Lets call them POI.
After getting those POIs I'm using splice to filter the three nearest POIs to the lat/lng Coordinates and filter on some specific keywords.
var radius = 1.5;
var POI = [];
var apiCall = $.get("CoorpAPI/" + radius + "/around/" + lat + "," + lng);
apiCall.done(function(result) {
var myLoc = result.filter(function(loc) {
return loc.id.substr(0, 3) != 'keyword';
});
$.each(myLoc, function(n, loc) {
POI.push(loc.id)
})
var top3 = POI.slice(0,3);
console.log(top3);
Now I want to run those three "top3" POIs ["AB1234", "BC2345", "CD3456"] against a second API which is returns location information.
Those information are supposed to be written into the same array into the second second dimension.
In the end I want to have something Like:
[
0: AB1234
Location Information: A
Location Information: B
1: CD2345
Location Information: C
Location Information: D
...
]
I guess the loop would have to look somewhat like this, but I'm not sure how to call the API and create a 2d-array out of the "top3" locations and the location information returned by the api:
for (var i = 0; i < top3.length; i++) {
var apiCall_2 = $.get("CoorpAPI_2"+top3[i]);
// ???
}
If I understand you correctly, you want to use a nested array inside POI to add more information after a second API call. One thing you can try is to push an array instead of just loc.id in the following manner:
POI.push([loc.id]);
Now you have a nested array in POI instead of a single string ID (I am guessing the ID is string; can be a number as well). For the second API call you can modify your code like this:
var apiCall_2 = $.get('CoorpAPI_2'+top3[i][0]);
In this way, you are using the ID which, is the first element in the nested array. Once you process all your data from API call 2, you can either push each data point separately into the nested array or, as another array like this:
// pushing each data points separately
top3[i].push(dataPoint1);
// ... up to say N data points
top3[i].push(dataPointN);
// adding as an array
top3[i].push([dataPoint1, dataPoint2, dataPointN]);
Your result will be like this:
[ ["AB1234", "dataPoint1", "dataPoint2"] ]
if you use the first approach and like this
[ [ "AB1234", ["dataPoint1", "dataPointN"] ], ]
if you use the second approach. Hope this helps.

Make changes of colors of icons visible in openlayers with a function

I try to accomplish that I will be able to change the color of marker icons to be visible in the map. They are in the map in different colors. Those colors are correspondenting to the json cat_id key's.
1: "http://dev.openlayers.org/img/marker.png",
2: "http://dev.openlayers.org/img/marker-blue.png",
3: "http://dev.openlayers.org/img/marker-gold.png",
4: "http://dev.openlayers.org/img/marker-green.png",
Each marker icon that is in the map is getting it's position, color and other valuable data from the json objects in the data id in the script tag. I didn't code the part of that work's close with the openlayer libary's. I wrote the following part of the total of the script:
var json = document.getElementById('data').innerHTML;
json = JSON.parse(json); // converts text into JSON
// search criteria (could be changed)
var $search_postal = "8912JB";
var $search_number = "10";
var $change_cat = 1;
function changeColor() {
for (var key in json) {
if (json.hasOwnProperty(key)) {
if (json[key].postal == $search_postal) {
if (json[key].number == $search_number) {
alert("Gonna change cat_id " + json[key].cat_id + " of the number search string " + $search_number + " of the postal search string " + $search_postal + " to cat_id " + $change_cat);
json[key].cat_id = "1";
alert('Changed!');
const posts = json; // the constant that is used to display the icons
var myJSON = json;
document.getElementById('demo').innerHTML = JSON.stringify(myJSON, undefined, 2); // changes of the json data to see on screen
}
}
}
}
}
const posts = json; //the constant that is used to display the icons
var myJSON = JSON.stringify(json);
document.getElementById('demo').innerHTML = myJSON;
This script will change the cat_id of the given search input. In the example it does a search for postal 8912JB with number 1. Once it has made the loop to find it's position it will change the cat_id value of 3 to 1. In other words the json data has been changed. Since it is stored in the const posts I replace this cons with the changed data. My problem is that I'm unable to refresh the marker icon(s) in the map with the new json data that is changed (cat_id: 1 of postal 8912JB number 10). This has to do with less knowledge about openlayers and Javascript. I'm struggling already 2 weeks with this. Can anybody help me to accomplish this? If it changes from color is the only thing that is required. I would only need to give the changes to the variables $search_postal, $search_number and $change_cat.
Here is the page for debug: https://jsfiddle.net/j4z1vpht/4/
Thanks for any help,
grid
You need to update the new category to the map feature, like this:
const updateFeatureCategory = (featureId, categoryId) => {
const feature = marker_layer.getSource().getFeatureById(featureId);
const post = feature.get("post");
const updatedPost = {
...post,
cat_id: categoryId
}
feature.set("post", updatedPost);
}
function changeColor() {
...
json[key].cat_id = "1";
updateFeatureCategory(key, "1");
...
}
Here's a working fiddle: https://jsfiddle.net/wsm2h3qz/1/

How to find the position of all array items from a loop

I'm brand new to programming so I apologize if this is a simple question.
I had a unique practice problem that I'm not quite sure how to solve:
I'm dealing with two arrays, both arrays are pulled from HTML elements on the page, one array is representing a bunch of states, and the next array is representing their populations. The point of the problem is to print the name of the states and their less than average populations.
To find and print all of the populations that are less than the average I used this code:
function code6() {
// clears screen.
clr();
// both variables pull data from HTML elements with functions.
var pop = getData2();
var states = getData();
var sum = 0;
for( var i = 0; i < pop.length; i++ ){
sum += parseInt( pop[i], 10 );
var avg = sum/pop.length;
if (pop[i] < avg) {
println(pop[i]);
// other functions used in the code to get data, print, and clear the screen.
function getData() {
var dataSource = getElement("states");
var numberArray = dataSource.value.split('\n');
// Nothing to split returns ['']
if (numberArray[0].length > 0) {
return(numberArray);
} else {
return [];
}
}
// Get the data from second data column
function getData2() {
var dataSource = getElement("pops");
var numberArray = dataSource.value.split('\n');
// Nothing to split returns ['']
if (numberArray[0].length > 0) {
return(numberArray);
} else {
return [];
}
}
// Clear the 'output' text area
function clr() {
var out = getElement("output");
out.value = "";
}
// Print to the 'output' HTML element and ADDS the line break
function println(x) {
if (arguments.length === 0) x = '';
print(x + '\n');
}
Now I just need to know how to get the value of these positions within the array so I can pull out the same positions from my states array and display them both side by side. Both arrays have the identical amount of items.
I hope this makes sense and thanks in advance to anyone who has time to take a look at this.
Best regards,
-E
Its a little hard to tell what you are trying to accomplish, but I guess you are going for something like:
'use strict'
function code6() {
const populations = ['39000000', '28000000', '21000000'];
const stateNames = ['california', 'texas', 'florida'];
const states = populations.map((population, i) => ({
'name': stateNames[i],
'population': Number(population),
}));
const sum = states.reduce((sum, state) => sum + state.population, 0);
const average = sum / populations.length;
states
.filter(state => state.population < average)
.forEach(state => {
const name = state.name;
const population = state.population;
console.log(`state name: ${name}, population: ${population}`);
});
}
// run the code
code6();
// state name: texas, population: 28000000
// state name: florida, population: 21000000
I took the liberty of refactoring your code to be a little more modern (es6) and Idiomatic. I hope its not to confusing for you. Feel free to ask any questions about it.
In short you should use:
'use strict' at the top of your files
const/let
use map/filter/forEach/reduce to iterate lists.
use meaningfull names
, and you should avoid:
classic indexed for-loop
parseInt
, and pretty much never ever use:
var
If your states array is built with corresponding indices to your pop one, like this:
states; //=> ['Alabama', 'Alaska', 'Arizona', ...]
pop; //=> [4863300, 741894, 6931071, ...]
then you could simply update your print statement to take that into account:
if (pop[i] < avg) {
println(state[i] + ': ' + pop[i]);
}
Or some such.
However, working with shared indices can be a very fragile way to use data. Could you rethink your getData and getData2 functions and combine them into one that returns a structure more like this the following?
states; //=> [
// {name: 'Alabama', pop: 4863300}
// {name: 'Alaska', pop: 741894},
// {name: 'Arizona', pop: 6931071},
// ...]
This would entail changes to the code above to work with the pop property of these objects, but it's probably more robust.
If your pop and state looks like:
var state = ['state1', 'state2', ...];
var pop = ['state1 pop', 'state2 pop', ...];
Then first of all, avg is already wrong. sum's value is running along with the loop turning avg's formula into sum as of iteration / array length instead of sum of all pops / array length. You should calculate the average beforehand. array.reduce will be your friend.
var average = pop.reduce(function(sum, val){return sum + val;}, 0) / pop.length;
Now for your filter operation, you can:
Zip up both arrays to one array using array.map.
Filter the resulting array with array.filter.
Finally, loop through the resulting array using array.forEach
Here's sample code:
var states = ['Alabama', 'Alaska'];
var pop = [4863300, 741894];
var average = pop.reduce(function(sum, val){return sum + val;}) / pop.length;
console.log('Average: ' + average);
states.map(function(state, index) {
// Convert 2 arrays to an array of objects representing state info
return { name: state, population: pop[index] };
}).filter(function(stateInfo) {
console.log(stateInfo);
// Filter each item by returning true on items you want to include
return stateInfo.population < average;
}).forEach(function(stateInfo) {
// Lastly, loop through your results
console.log(stateInfo.name + ' has ' + stateInfo.population + ' people');
});

covert large array of objects into smaller array objects using javascript

I have an list of values like this from a sql database.
UserName Email ComputerName DateIssued
jjsmith jjsmith#example.com JTComputer 9/14/2013
ltjoseph ltjoseph#example.com LTComputer1 10/21/2013
KTsmith KevinTem#example.com KTComputer1 01/25/2012
ltjoseph ltjoseph#example.com LTComputer2 01/11/2013
KTsmith KevinTem#example.com KTComputer2 01/25/2012
I transform my list into an array of objects.
var user_array = [
{"username":"jjsmith", "email":"jjsmith#example.com", "computerName":"JTComputer", "dateissued":"10/21/2013"}
{"username":"ltjoseph", "email":"ltjoseph#example.com", "computerName":"LTComputer1", "dateissued":"10/21/2013"}
{"username":"KTsmith", "email":"KevinTem#example.com", "computerName":"KTComputer1", "dateissued":"01/25/2012"}
{"username":"ltjoseph", "email":"ltjoseph#example.com", "computerName":"LTComputer2", "dateissued":"01/11/2013"}
{"username":"KTsmith", "email":"KevinTem#example.com", "computerName":"KTComputer2", "dateissued":"01/25/2012"}]
A function has been created by someone else that sends emails to users, it only accepts two parameters which are strings.
So I don't want to send more than 1 email per user. So I am trying to figure out how to combine the items together so that my an example set of strings look like this.
var str1 = "ltjoseph#example.com";
var str2 = "ltjoseph, LTComputer1-10/21/2013, LTComputer2-01/11/2013";
and then fire the other user function to send emails for each of the items in the list.
function sendEmails(str1, str2);
If anyone has any ideas how i can do this. Please advise..
var by_user = {};
for (var i = 0; i < user_array.length; i++) {
if (by_user[user_array[i].username]) {
// Found user, add another computer
by_user[user_array[i].username].str2 += ', ' + user_array[i].computerName + '-' + user_array[i].dateissued;
} else {
// First entry for user, create initial object
by_user[user_array[i].username] = {
str1: user_array[i].email,
str2: user_array[i].username + ', ' + user_array[i].computerName + '-' + user_array[i].dateissued
};
}
}
Now you have the by_user object, which has a single sub-object for each user, whose str1 and str2 properties are the variables you want.
by_user['ltjoseph'].str1 => ltjoseph#example.com
by_user['ltjoseph'].str2 => ltjoseph, LTComputer1-10/21/2013, LTComputer2-01/11/2013
something like this:
var str1=array[0].email
var str2=array[0].username+", "+array[0].computerName+array[0].dateissued
or use a loop and iterate through the array
I strongly recommend bringing in a library like lodash for this sort of thing and using uniq (sample here: http://jsfiddle.net/MwYtU/):
var uniqs = lodash(user_array).pluck('email').uniq().value();
If you're doing javascript and aren't acquainted with lodash or underscore, go do that because it'll save you a lot of time. Using tried and true code is a good idea. Added bonus: if you want to see how the pros are doing something like uniq you can just look at the source code.

Categories

Resources