D3.js array double quotes after .map - javascript

I have the following code:
d3.csv("static/data/river.csv", function(data) {
var latlongs = data.map(function(d) { return [d.Lat,d.Lng]; })
var lineArray1 = latlongs;
console.log(lineArray1);
I get an output lineArray1 that looks like [Array(2), Array(2), Array(2)....] and so on. But when I take a look at the actual Array(2)'s they look like:
["-35.48642101", "144.8891555"]
["-35.48695061", "144.8893026"]
["-35.48704283", "144.889315"]
Is there a way to get rid of the double quotes at the start? I tried lineArray1.map(Number) but this just generated an array of NaNs for some reason. The output I want is:
[-35.48642101, 144.8891555]
[-35.48695061, 144.8893026]
[-35.48704283, 144.889315]
Thanks!

It looks like d.Lat and d.Lng are strings, so if you want to convert them to numbers, call Number on them:
var latlongs = data.map(function(d) { return [Number(d.Lat), Number(d.Lng)]; });
Or, to not repeat Number twice, use .map again inside:
var latlongs = data.map(function(d) { return [d.Lat, d.Lng].map(Number); });
Or, in modern JS:
const latlongs = data.map(({ Lat, Lng }) => [Lat, Lng].map(Number));
Your lineArray1.map(Number) didn't work because lineArray1 contains arrays (of numbers), and not numbers alone, and calling Number on an array doesn't work.

Related

how to change thousands line of number to an array in JavaScript

I got thousands lines of number
142156
108763
77236
78186
110145
126414
115436
133275
132634
......
82606
and I wanna change it to an array [142156, 108763, 108763, 77236, 78186, ....]
If I could make all these number assigned to a variable, I could choose either to use the RegExp or to convert to string first and then array.
any idea how to make it as a variable or other better suggestions?
Read as string from file then split the string at line breaks and map the resultant array of strings to number
const str = `142156
108763
77236
78186
110145
126414
115436
133275
132634`;
const arr = str.split(/\r?\n/).map(Number)
console.log(arr)
You can use following method.
const nums = document.getElementById("numbersDiv").innerHTML;
const numsToArr = nums.split('\n').map(Number)
console.log({ numsToArr } )
<div id="numbersDiv">142156
108763
77236
78186
110145
126414
115436
133275
132634</div>

JSON to JS array

JSON:
[{"CDATE":"0000-00-00","DISTANCE":"0"},
{"CDATE":"0000-00-00","DISTANCE":"1"},
{"CDATE":"0000-00-00","DISTANCE":"2"},
{"CDATE":"0000-00-00","DISTANCE":"3"}]
Is it possible to put all the distance value in their own array in JS? The formatting will be consistent as it comes from an API and is always formatted correctly.
What I've tried:
var arry = [ /* JSON noted above */ ];
alert(arry[1])
and
var arry = JSON.parse([ /* JSON noted above */ ]);
alert(arry[1])
Expected:
1
Actual:
{"CDATE":"0000-00-00","DISTANCE":"1"}
and the other gives an error.
I would like to extract just the DISTANCE value as an array of DISTANCE
I've tried JSON.parse() but I don't think this is what I am after as it hasn't worked for me.
Use .map
var data = [{"CDATE":"0000-00-00","DISTANCE":"0"},
{"CDATE":"0000-00-00","DISTANCE":"1"},
{"CDATE":"0000-00-00","DISTANCE":"2"},
{"CDATE":"0000-00-00","DISTANCE":"3"}];
var distance = data.map(el => el.DISTANCE);
console.log(distance[2]);
console.log(distance);
It is already a valid json so you do not need to use JSON.parse()

convert array to array of array

I am getting data from a Firebase database and want to be able to pass it into a function to be used in a Google Map. The required/desired format is below. I can get the data from Firebase into an but want to reformat it somehow to put it into the correct format.
I have passed the array itself and then tried to push it into the locations array but that obviously doesn't work.
Here is a console.log(); of the array and the format.
Current Array:
var array = ["Stop1, 37.3329891813207, -122.039420719004", "Stop2, 37.3320091546085, -122.036849794357", "Stop3, 37.3310547072562, -122.034668026436", "Stop4, 37.3301791417375, -122.033242200136", "Stop5, 37.3307185698498, -122.030606204886"]
initMap(array)
Desired Format:
function initMap(passedArray) {
//..Convert array here?..
var locations = [
['Stop1', 37.3329891813207, -122.039420719004],
['Stop2', 37.3320091546085, -122.036849794357],
['Stop3', 37.3310547072562, -122.034668026436],
['Stop4', 37.3301791417375, -122.033242200136],
['Stop5', 37.3307185698498, -122.030606204886]
];
}
Thanks.
Split by separator ', ' and parse numbers.
var array = ["Stop1, 37.3329891813207, -122.039420719004", "Stop2, 37.3320091546085, -122.036849794357", "Stop3, 37.3310547072562, -122.034668026436", "Stop4, 37.3301791417375, -122.033242200136", "Stop5, 37.3307185698498, -122.030606204886"]
const initMap = array => array
.map(str => str.split(', ').map((x, i) => (i ? parseFloat(x) : x)))
console.log(initMap(array))

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

ignoring a group with the D3 nest function

I have some data where, in a given column of a csv, there are six possible values:
1,2,3,4,5,NaN.
I am currently trying to group the data using the d3.nest and rollup functions. My goal is to group the data but exclude "NaN" values in the final output.
This is my current code:
var nested = d3.nest()
.key(function(d){return d[question];
})
.rollup(function(leaves){
var total = data.length
var responses = leaves.length;
return {
'responses' : responses,
'percent' : responses/total
};
})
.entries(data)
As you can see, I would like to return both a count of each of the categories as well as the percentage of the total that they represent. After removing NaN, I would also like the removal of NaN represented in percentage values of all of the other categories so that they sum to 100%.
The easiest way to do this is to remove the rows the contain NaN before passing the data to d3.nest():
var filtered = data.filter(function(d) { return d.question !== 'NaN'; });

Categories

Resources