As the title says, I'm trying to count groups of data within groups of data: My logic is to group all the data into states, then group date into years. so that the output should look like something like:
state,year,count
mo,1910,2
in,1910,1
il,1910,3
or,1910,4
co,1910,2
nd,1910,1
...
mo,1911,5
in,1911,4
il,1911,6
or,1911,2
co,1911,8
The CSV I'm using has a lot more columns that needed, I'm only interested in the columns state and year. My code below isn't working, any help would be great.
const countStates = filteredData.reduce((m, d) => {
if(!m[d.year]){
m[d.year] = {...d, count: 1};
return m;
}
m[d.state];
m[d.year];
m[d.year].count += 1;
return m;
},{});
const countedStates = Object.keys(countStates).map((k) => {
const item = countStates[k];
return {
state: item.state,
year: item.year,
count: item.count
}
})
Edit
Example of the dataset I'm using:
datetime,city,state,country,shape,duration (seconds),duration (hours/min),comments,date posted,latitude,longitude
10/10/1949 20:30,san marcos,tx,us,cylinder,2700,45 minutes,"This event took place in early fall around 1949-50. It occurred after a Boy Scout meeting in the Baptist Church. The Baptist Church sit",4/27/2004,29.8830556,-97.9411111
10/10/1949 21:00,lackland afb,tx,,light,7200,1-2 hrs,"1949 Lackland AFB, TX. Lights racing across the sky & making 90 degree turns on a dime.",12/16/2005,29.38421,-98.581082
10/10/1955 17:00,chester (uk/england),,gb,circle,20,20 seconds,"Green/Orange circular disc over Chester, England",1/21/2008,53.2,-2.916667
10/10/1956 21:00,edna,tx,us,circle,20,1/2 hour,"My older brother and twin sister were leaving the only Edna theater at about 9 PM,...we had our bikes and I took a different route home",1/17/2004,28.9783333,-96.6458333
10/10/1960 20:00,kaneohe,hi,us,light,900,15 minutes,"AS a Marine 1st Lt. flying an FJ4B fighter/attack aircraft on a solo night exercise, I was at 50ꯠ' in a "clean" aircraft (no ordinan",1/22/2004,21.4180556,-157.8036111
10/10/1961 19:00,bristol,tn,us,sphere,300,5 minutes,"My father is now 89 my brother 52 the girl with us now 51 myself 49 and the other fellow which worked with my father if he's still livi",4/27/2007,36.5950000,-82.1888889
10/10/1965 21:00,penarth (uk/wales),,gb,circle,180,about 3 mins,"penarth uk circle 3mins stayed 30ft above me for 3 mins slowly moved of and then with the blink of the eye the speed was unreal",2/14/2006,51.434722,-3.18
10/10/1965 23:45,norwalk,ct,us,disk,1200,20 minutes,"A bright orange color changing to reddish color disk/saucer was observed hovering above power transmission lines.",10/2/1999,41.1175000,-73.4083333
10/10/1966 20:00,pell city,al,us,disk,180,3 minutes,"Strobe Lighted disk shape object observed close, at low speeds, and low altitude in Oct 1966 in Pell City Alabama",3/19/2009,33.5861111,-86.2861111
10/10/1966 21:00,live oak,fl,us,disk,120,several minutes,"Saucer zaps energy from powerline as my pregnant mother receives mental signals not to pass info",5/11/2005,30.2947222,-82.9841667
10/10/1968 13:00,hawthorne,ca,us,circle,300,5 min.,"ROUND , ORANGE , WITH WHAT I WOULD SAY WAS POLISHED METAL OF SOME KIND AROUND THE EDGES .",10/31/2003,33.9163889,-118.3516667
10/10/1968 19:00,brevard,nc,us,fireball,180,3 minutes,"silent red /orange mass of energy floated by three of us in western North Carolina in the 60s",6/12/2008,35.2333333,-82.7344444
10/10/1970 16:00,bellmore,ny,us,disk,1800,30 min.,"silver disc seen by family and neighbors",5/11/2000,40.6686111,-73.5275000
And the code I used to filter out the data:
fs.createReadStream('./data/scrubbed.csv')
.pipe(readCSV())
.on('data', (data) => CSV.push(data))
.on('end', () => {
let data = CSV.map((d) => {
return {
year: new Date (d.datetime).getFullYear(),
state: d.state,
country: d.country
}
});
filteredData = data.filter((d) => {
return d.state !== "" && d.country === "us"
})
Which returns this (an example of the dataset):
[ { year: 1949, state: 'tx', country: 'us' },
{ year: 1956, state: 'tx', country: 'us' },
{ year: 1960, state: 'hi', country: 'us' },
{ year: 1961, state: 'tn', country: 'us' },
{ year: 1965, state: 'ct', country: 'us' }...
The above is what I'm trying to group twice using reduce
The below code gets an array of states with the year and using reduce we are getting the count of each state grouped by year as
var data = [
{ year: '1910', state: 'mo', country: 'us' },
{ year: '1910', state: 'in', country: 'us' },
{ year: '1910', state: 'il', country: 'us' },
{ year: '1910', state: 'mo', country: 'us' },
{ year: '1911', state: 'in', country: 'us' },
{ year: '1911', state: 'il', country: 'us' },
{ year: '1911', state: 'mo', country: 'us' },
{ year: '1911', state: 'in', country: 'us' }
];
var organizedData = data.reduce((acc, val, index) => {
acc[val.state] = acc[val.state] || {};
acc[val.state][val.year] = (+acc[val.state][val.year] || 0) + 1;
return acc;
}, {});
console.log(organizedData);
Related
Learning JS here, I have a code that already does what I need but wanted to see if I could do it with the .map() method.
In a nutshell, this code appends a table to a web page using the data stored in filteredSightings.
let filteredSightings = [{
datetime: "1/1/2010",
city: "benton",
state: "ar",
country: "us",
shape: "circle",
durationMinutes: "5 mins.",
comments: "one bright green light at my front door."
},
{
datetime: "1/1/2010",
city: "bonita",
state: "ca",
country: "us",
shape: "light",
durationMinutes: "13 minutes",
comments: "Three bright red lights witnessed floating"
},
... and so on
so this does the job:
let tbody = d3.select("tbody");
filteredSightings.forEach((sight) => {
let row = tbody.append("tr");
Object.entries(sight).forEach(([key, value]) => {
let cell = row.append("td");
cell.text(value);}
);
});
And now I'm trying to change it so that i can use .map() but can't find a way to "translate" forEach(([key, value]) into .map().
This is with what I came up so far:
filteredSightings.map(sight => tbody.append("tr").append("td").text(sight.datetime));
I need to write a conditional that checked each image value and if its empty displays a stock photo 'selfie.jpg' and if it is not then display whatever is inside of it.
I know how to access it beat.officers[0].image. what I don't know is how to make the program check through the length of officers for each items image value, check if its empty and then display a photo based on the results of that check.
pls help its for a test.
A image of the Json object I am trying to work with
const policeData = [
{
beat:
{
name: 'Portishead',
latLong: ' ',
introText: 'Contact your local policing team, find opportunities to meet the team and view or contribute to community policing priorities for your area.',
officers: [
{
name: 'Trevor Dyson',
role: 'Neighbourhood Police Team Sergeant',
image: ''
},
{
name: 'Kirsten Karcher',
role: 'Police Community Support Officer',
image: 'kkarcher.jpg'
},
{
name: 'Bill Hoover',
role: 'Police Community Support Officer',
image: ''
},
{
name: 'Andrew Henry',
role: 'Partnership Support Officer',
image: ''
}
],
priorities: [
{
title: 'Road Safety Week',
updated: '18 November 2019',
path: '/road-safety-week/'
},
{
title: 'Community SpeedWatch',
updated: '14 August 2019',
path: '/community-speedwatch/'
},
{
title: 'Mopeds using footpaths and speeding vehicles',
updated: '04 September 2019',
path: '/mopeds-using-footpaths-and-speeding-vehicles/'
}
]
}
}];
So here is my template which is functional. As you can see though its not dynamic and I tried to input the conditional as a function with an if statement but its just not working. I did consider trying the turnery (condition : if yes : if no) but I struggled with that too.
Some of the image values are empty you see? Ultimately, I am trying to make it go through each object and check its image value and then run the conditional.
function kk(police) {
officers = police.beat.officers.length;
return `
<div class=person>
<img class="pol-photo" src = "${photoO(police.beat.officers[0])}"
<h2 class ="pol-name">${police.beat.officers[1].name}</h2>
<p> ${police.beat.officers[1].role}</p>
</div>
`
}
function photoO(pol) {
if (pol == '' ) {
return 'officer-profile.jpg'
} else {
return 'kkarcher.jpg'
}
}
You can use the functions from below to get the correct output. One function will return the HTML for just one officer while the other will return the HTML of all of them. You can test it below.
const policeData = [
{
beat:
{
name: 'Portishead',
latLong: ' ',
introText: 'Contact your local policing team, find opportunities to meet the team and view or contribute to community policing priorities for your area.',
officers: [
{
name: 'Trevor Dyson',
role: 'Neighbourhood Police Team Sergeant',
image: ''
},
{
name: 'Kirsten Karcher',
role: 'Police Community Support Officer',
image: 'kkarcher.jpg'
},
{
name: 'Bill Hoover',
role: 'Police Community Support Officer',
image: ''
},
{
name: 'Andrew Henry',
role: 'Partnership Support Officer',
image: ''
}
],
priorities: [
{
title: 'Road Safety Week',
updated: '18 November 2019',
path: '/road-safety-week/'
},
{
title: 'Community SpeedWatch',
updated: '14 August 2019',
path: '/community-speedwatch/'
},
{
title: 'Mopeds using footpaths and speeding vehicles',
updated: '04 September 2019',
path: '/mopeds-using-footpaths-and-speeding-vehicles/'
}
]
}
}];
// helper function to check if value is empty
function existsAndNotEmpty(value) {
if (typeof value != 'undefined' && value.length > 0) {
return true;
}
return false;
}
function getOfficerHTML(officer) {
let result = "";
if( existsAndNotEmpty(officer.image) ) {
result += '<img class="pol-photo" src = "' + officer.image + '" />';
} else {
result += '<img class="pol-photo" src = "officer-profile.jpg" />';
}
if( existsAndNotEmpty(officer.name) ) {
result += '<h2 class ="pol-name">' + officer.name + '</h2>';
} else {
result += '<h2 class ="pol-name">Unknown officer</h2>';
}
if( existsAndNotEmpty(officer.role) ) {
result += '<p>' + officer.role + '</p>';
} else {
result += '<p>Unknown role</p>';
}
return result;
}
function getAllOfficerHTML() {
let result = "";
let officerLength = policeData[0].beat.officers.length;
let officers = policeData[0].beat.officers;
for(var i=0; i < officerLength; i++){
result += getOfficerHTML(officers[i]);
}
return result;
}
// Now you can use it like this to print a single officer
var singleOfficer = getOfficerHTML(policeData[0].beat.officers[1]);
console.log(singleOfficer);
// or like this to get all ooficers at once
var allOfficers = getAllOfficerHTML();
console.log(allOfficers);
I want to fetch year, category, id and share of a particular nobel prize winner from the json data, by giving firstname and surname as raw input. I am able to get id and share easily from the below code but how can I get year and category.
Here is my code:
var json = {"prizes":
[{"year":"2018",
"category":"physics",
"overallMotivation":"\u201cfor groundbreaking inventions in the field of laser physics\u201d",
"laureates":[
{"id":"960",
"firstname":"Arthur",
"surname":"Ashkin",
"motivation":"\"for the optical tweezers and their application to biological systems\"",
"share":"2"},
{"id":"961",
"firstname":"G\u00e9rard",
"surname":"Mourou",
"motivation":"\"for their method of generating high-intensity, ultra-short optical pulses\"",
"share":"4"},
{"id":"962",
"firstname":"Donna",
"surname":"Strickland",
"motivation":"\"for their method of generating high-intensity, ultra-short optical pulses\"",
"share":"4"}
]}
]};
var winner = json.prizes.reduce((acc, winners) =>
(acc.push(...winners.laureates), acc), []).find(i => i.id === '960')
console.log(winner);
For the sake of completeness, I have added miultiple prizes in my test input. I hope that is allright. Try this code.
const input = {
prizes: [
{
year: "2018",
category: "physics",
overallMotivation:
"\u201cfor groundbreaking inventions in the field of laser physics\u201d",
laureates: [
{
id: "960",
firstname: "Arthur",
surname: "Ashkin",
motivation:
'"for the optical tweezers and their application to biological systems"',
share: "2"
},
{
id: "961",
firstname: "G\u00e9rard",
surname: "Mourou",
motivation:
'"for their method of generating high-intensity, ultra-short optical pulses"',
share: "4"
},
{
id: "962",
firstname: "Donna",
surname: "Strickland",
motivation:
'"for their method of generating high-intensity, ultra-short optical pulses"',
share: "4"
}
]
},
{
year: "2019",
category: "chemistry",
overallMotivation:
"\u201cfor groundbreaking inventions in the field of laser physics\u201d",
laureates: [
{
id: "960",
firstname: "Arthur",
surname: "Ashkin",
motivation:
'"for the optical tweezers and their application to biological systems"',
share: "2"
},
{
id: "961",
firstname: "G\u00e9rard",
surname: "Mourou",
motivation:
'"for their method of generating high-intensity, ultra-short optical pulses"',
share: "4"
},
{
id: "123",
firstname: "Donna",
surname: "Strickland",
motivation:
'"for their method of generating high-intensity, ultra-short optical pulses"',
share: "6"
}
]
}
]
};
function find(firstName, surname) {
return input.prizes.map(prize => {
const filteredLaureate = prize.laureates.filter(
laureate =>
laureate.firstname === firstName && laureate.surname === surname
);
return filteredLaureate.map(i => {
return {
id: i.id,
share: i.share,
category: prize.category,
year: prize.year
};
});
}).flat();
}
const response = find("Donna", "Strickland");
console.log(response);
Try this code.
let winners = [];
json.prizes.forEach(e => {
let data = { year: e.year, category: e.category };
const laureates = e.laureates.find( item => {
return item.firstname === 'Arthur' && item.surname === 'Ashkin';
});
data = { ...data, ...laureates };
winners.push(data);
});
console.log(winners);
The code above will give output like this:
[{
category: "physics",
firstname: "Arthur",
id: "960",
motivation: "\"for the optical tweezers and their application to biological systems\"",
share: "2",
surname: "Ashkin",
year: "2018"
}]
Remember, the code above will not perform very good when the dataset is large.
How can query in Mongo DB , by the way I am using Keystone JS. I wanted to filter or get result from the Vehicle Model where keys and values from for example { 'Year' => '2019,2018', 'Make' => 'Acura,BMW' } . It will filter where year = 2019 , 2018 same with the Make.
My current code
view.on('init', function (next) {
var q = keystone.list('Vehicle').paginate({
page: req.query.page || 1,
perPage: 10,
maxPages: 10,
filters: {
state: 'published',
},
})
.sort('-publishedDate')
if (locals.filters.searchkeys) {
let urlSearchParams = new URLSearchParams(locals.filters.searchkeys)
for (var key of urlSearchParams.keys()) {
console.log("The Key :" , key)
//this part is where it would be dynamic
q.where('Year').in();
}
}
Search Param
{ 'Year' => '2019,2018', 'Make' => 'Acura,BMW' }
Collection
{ total: 12,
results:
[ { _id: 5d6893cdc02d0e3020f84c85,
DriveType: 'FWD',
FuelType: 'Gasoline Fuel',
ImageList:
'',
Options:
'Traction Control,Stability Control,Front Wheel Drive,Tires - Front All-Season,Tires - Rear All-Season,Aluminum Wheels,Power Steering,4-Wheel Disc Brakes,ABS,Brake Assist,Sun/Moonroof,Generic
Sun/Moonroof,Rear Spoiler,Automatic Headlights,Fog Lamps,Heated Mirrors,Power Mirror(s),Privacy Glass,Intermittent Wipers,Variable Speed Intermittent Wipers,Leather Seats,Power Driver Seat,Bucket Seats,Heated Front Seat(s),Driver Adjustable Lumbar,Passenger Adjustable Lumbar,3rd Row Seat,Pass-Through Rear Seat,Floor Mats,Steering Wheel Audio Controls,Adjustable Steering Wheel,Engine Immobilizer,Tire Pressure Monitor,Power Windows,Power Door Locks,Universal Garage Door Opener,Keyless Entry,Cruise Control,Security System,Climate Control,A/C,Rear A/C,Rear Defrost,AM/FM Stereo,CD Changer,CD Player,Satellite Radio,Entertainment System,Power Outlet,Driver Vanity Mirror,Passenger Vanity Mirror,Driver Illuminated Vanity Mirror,Passenger Illuminated Visor Mirror,Rear Reading Lamps,Driver Air Bag,Passenger Air Bag,Front Side Air Bag,Passenger Air Bag Sensor,Front Head Air Bag,Rear Head Air Bag,Child Safety Locks',
Description: '',
DateInStock: '7/15/2019',
Invoice: 3000,
BookValue: '3686',
MSRP: 0,
SellingPrice: 5592,
Miles: 162111,
Transmission: 'Automatic',
EngineDisplacement: '3.5L',
EngineCylinders: '6',
InteriorColor: '',
ExteriorColor: 'Gray',
Doors: 4,
ModelNumber: 'YF2867JNW',
Trim: 'Ex-L',
Body: 'Convertible',
Model: 'Pilot',
Make: 'Honda',
Year: 2007,
VIN: '5FNYF28677B037628',
Stock: 'K2501A',
Type: 'Used',
image_gallery: [],
__v: 0,
CategorizedOptions: '',
Comment: '',
name: '',
publishedDate: null,
content: [Object],
categories: [],
image: [Object],
state: 'published',
Certified: true } ],
currentPage: 1,
totalPages: 2,
pages: [ 1, 2 ],
previous: false,
next: 2,
first: 1,
last: 1 }
let's say query is request params coming to backend as
let request={'Year':'2019,2018', 'Make':'Acura,BMW'}
let query={}
if(request.Year){
let year=request.Year.split(',') // will give array ['2019','2018']
for(let i=0;i<year.length;i++){ //for making array of nos [2019,2018]
year[i]=parseInt(year[i])
}
query.Year={$in:year} // {$in:['2019','2018']}
}
if(request.Make){
query.Make={$in:request.Make.split(',')} // {$in:['Acura','BMW']}
}
var Vehicle = keystone.list('Vehicle');
let q= Vehicle.model.find(query)
.where('state', 'published')
.populate('author')
.sort('-publishedAt')
.limit(5)
.exec(function(err, posts) {
// do something with posts
});
I have a mustache file, and I am iterating over the array:
var data = {
sales: [
{
name: "Jim Frost",
region: "USA East",
phone: "212-555-1212",
email: "jfrost#acme-travel.com"
},
{
name: "Jan Smith",
region: "USA West",
phone: "310-555-1212",
},
{
name: "Fred Wesley",
phone: "608-555-1212",
email: "fwesley#acme-travel.com"
},
{
name: "Lisa Moore",
region: "USA South",
phone: "315-555-1212",
email: "lmoore#acme-travel.com"
},
{
name: "Jim Dio",
phone: "+ 44 022-555-1212",
email: "jdio#acme-travel.com"
},
{
name: "Charles Watts",
region: "Spain",
email: "cwatts#acme-travel.com"
},
{
name: "Bert Cooper",
region: "Italy",
email: "bcooper#acme-travel.com"
}
]
};
here is the markup:
<div>
<section>
{{#data.sales}}
<article class="items">
<div class="region">{{{region}}}</div>
</article>
{{/data.sales}}
</section>
</div>
I want to add some special style (like, bold font, color etc) ONLY if the region is USA East.
how can i detect inside this inherent loop in the article element if {{{region}} has a specific value? Given that the comparison will be made against a value that i get from backend, say {{myValue}}, which is manually set to USA East in the backend.
You can add a function in the data which will return the correct class depending on the region value. Something like
data['regionClass'] = function(){
if ( this['region'] == 'USA East' ) {
return "strong green";
}else{
return "";
}
}
And then in the Mustache you can do: <div class="region {{regionClass}}">{{{region}}}</div>