Fetch specific informations from complex json object - javascript

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.

Related

Looping ant design tag color in React Js

I use Ant Design and data which coming from API. I assume the data like this
data = [
{
name: "John",
job: "Freelancer",
},
{
name: 'Bob',
job: 'UI Designer'
},
{
name: 'Sam',
job: 'CEO'
},
{
name: 'Alex',
job: 'Mobile Dev'
},
{
name: 'Jess',
job: 'Web Dev'
},
];
I want to return the job with Tag from Ant Design which the tag has a different color
<Tag color="green">green</Tag>
<Tag color="cyan">cyan</Tag>
I have looped the data. but I don't know how to make the data have a different color tag
data.map((el) => {
//This example doesn't have color
return <Tag>{el.job}</Tag>
})
How to achieve that ? And sorry i'm not good enough in English. I hope you understand what i mean
Or you can visit code sandbox here
In your data, add a property something like tagColor for each object.
data = [
{
name: "John",
job: "Freelancer",
tagColor: "red"
},
{
name: 'Bob',
job: 'UI Designer'
tagColor: "green"
},
{
name: 'Sam',
job: 'CEO'
tagColor: "blue"
},
];
Then in the loop, use that property to dynamically add colors. Like,
data.map((el) => {
return <Tag color={el.tagColor}>{el.job}</Tag>
});
Updated
If the colors can be random, you can place all your colors in an array. And you can pick colors one by one using index or even a randomiser. Something like,
const colors = ["red", "blue", "green"];
data.map((el, i) => {
return <Tag color={colors[(i%colors.length)]}>{el.job}</Tag>
});
It will pick colors in the array one by one based on index.

Figuring out .map() method

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

Assign array values to top level object javascript

At the bottom is a slimmed down version of a JSON file that I am trying to parse. I would like to create individual objects that have a key for the team name and the player name.
How would I go about using the team name and mapping to each individual player and receive something like this (using javascript):
[
{ name: 'Dallas Stars', playerName: 'Alexander Radulov'},
{ name: 'Dallas Stars', playerName: 'Ben Bishop'},
{ name: 'Dallas Stars', playerName: 'Jamie Benn'}
...
{ name: 'Columbus Blue Jackets', playerName: 'Pierre-Luc Dubois'}
]
From this JSON:
[ { name: 'Dallas Stars',
roster:
[ 'Alexander Radulov',
'Ben Bishop',
'Jamie Benn',
'Tyler Pitlick',
'Miro Heiskanen' ] },
{ name: 'Los Angeles Kings',
roster:
[ 'Jonathan Quick',
'Jonny Brodzinski',
'Oscar Fantenberg' ] },
{ name: 'San Jose Sharks',
roster:
[ 'Joe Thornton',
'Brent Burns',
'Joe Pavelski',
'Antti Suomela' ] },
{ name: 'Columbus Blue Jackets',
roster:
[ 'Sonny Milano',
'Brandon Dubinsky',
'Nick Foligno',
'Pierre-Luc Dubois' ] } ]
Essentially I am trying to map a top level key pair to individual players. I have tried searching through all lodash functions as well and haven't stumbled upon the correct way to do this.
Is there a way to use a flat map and have the team name used multiple times?
You need to iterate over the outer array items, and then inside of each of those, iterate over the roster too. reduce is usually the most appropriate method for transforming an array into another array on a non-one-to-one basis:
const input=[{name:'Dallas Stars',roster:['Alexander Radulov','Ben Bishop','Jamie Benn','Tyler Pitlick','Miro Heiskanen']},{name:'Los Angeles Kings',roster:['Jonathan Quick','Jonny Brodzinski','Oscar Fantenberg']},{name:'San Jose Sharks',roster:['Joe Thornton','Brent Burns','Joe Pavelski','Antti Suomela']},{name:'Columbus Blue Jackets',roster:['Sonny Milano','Brandon Dubinsky','Nick Foligno','Pierre-Luc Dubois']}];
const output = input.reduce((a, { name, roster }) => {
roster.forEach((playerName) => {
a.push({ name, playerName });
});
return a;
}, []);
console.log(output);
You can also use map and flat.
Map over the original array, then for each item being "mapped" map over its roster and create your desired object. Finally, since the resulting array will be 2d, flatten it:
var data = [{ name: 'Dallas Stars', roster: ['Alexander Radulov', 'Ben Bishop', 'Jamie Benn', 'Tyler Pitlick', 'Miro Heiskanen' ] }, { name: 'Los Angeles Kings', roster: ['Jonathan Quick', 'Jonny Brodzinski', 'Oscar Fantenberg' ] }, { name: 'San Jose Sharks', roster: ['Joe Thornton', 'Brent Burns', 'Joe Pavelski', 'Antti Suomela' ] }, { name: 'Columbus Blue Jackets', roster: ['Sonny Milano', 'Brandon Dubinsky', 'Nick Foligno', 'Pierre-Luc Dubois' ] } ];
var res = data
.map(({name, roster}) =>
roster.map(playerName => ({name, playerName})))
.flat();
console.log(res);

html5 mustache get the index of article and compare the value

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>

Javascript error trying to perform a search filter using Angular JS

In my app Im trying perform a search filter on names by partial match from the beginning. Heres an example of what Im trying to do:
Lets say I have a list of names:
Ben
James
Adam
Judy
Andy
and enter the text "a" in my search field, it would return
Adam
Andy
if I further enter "an" in my search field, it would return
Andy
In my app.js, I have the code:
var myApp = angular.module("myApp", []);
myApp.controller("myController", function ($scope) {
var employees = [
{ name: "Ben", gender: "Male", salary: 55000, city: "London" },
{ name: "Jane", gender: "Female", salary: 62000, city: "Albany" },
{ name: "Rick", gender: "Male", salary: 65000, city: "Los Angeles" },
{ name: "Pam", gender: "Female", salary: 60000, city: "Paris" },
{ name: "Josh", gender: "Male", salary: 68000, city: "Brussels" },
];
$scope.employees = employees;
$scope.filtered = function (item) {
if ($scope.searchName == undefined) {
return true;
} else {
if (item.name.toLowerCase().startsWith($scope.searchName.toLowerCase()) != -1) {
return true;
}
}
return false;
}
});
And in my html page, I have the following line which displays the list of employees:
<tr ng-repeat="employee in employees | filter: filtered">
And the following line which the user inputs the search text:
<input type="text" placeholder="Search Name" ng-model="searchName.name"> <br><br>
However, when I attempt to test this, I get the error:
Error: $scope.searchName.toLowerCase is not a function. (In '$scope.searchName.toLowerCase()', '$scope.searchName.toLowerCase' is undefined)
As your ng-model is set to searchName.name, $scope.searchNameis an object, therefore it has no .toLowerCase() function.
You need to adjust your if-case like this:
if (item.name.toLowerCase().startsWith($scope.searchName.name.toLowerCase()) !== -1) {}
Furthermore, it is advisable to use identity operators instead of equality operators, unless strict identity is explicitly not needed.
The ng-model is set to searchName.name, so you may need to call on $scope.searchName.name.toLowerCase() instead of $scope.searchName.toLowerCase()

Categories