Assign array values to top level object javascript - 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);

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.

How to make a group of same values

I have a simply array and want to loop through the array which have some same key and value, and i want to make a group of those values which are the same and put the related item under that.
export class AppComponent implements OnInit {
data = [
{
'con': 'Usa',
'city': 'ny',
'town':'as'
},
{
'con': 'Ger',
'city': 'ber',
'town':'zd'
},
{
'con': 'Usa',
'city': 'la',
'town':'ss'
}
];
array: any[] = [];
ngOnInit() {
this.array = this.data;
}
}
html:
<div *ngFor="let item of array ">
<h3>{{item.con}}</h3>
<p>{{item.city}}</p>
<p>{{item.town}}</p>
<hr>
</div>
and i have a following result:
Usa
ny
as
-----
Ger
ber
zd
-----
Usa
la
ss
-----
but what i really wants is to make a group of those country with the same name and display the related cities and town under that with the following format:
[{
"con": "usa",
"area": [{
"city": "ny",
"town": "as"
}, {
"city": "la",
"town": "ss"
}]
},
{
"con": "ger",
"area": [{
"city": "ber",
"town": "zd"
}]
}
]
Transform the data to an array with the consolidated objects, where the cities properties have arrays, like so
[
{ con: "Usa": cities: ["ny", "la"] },
{ con: "Ger", cities: ["ber"] }
]
You can build that data structure as follows:
this.array = Array.from(
this.data.reduce(
(map, {con, city}) => map.set(con, (map.get(con) || []).concat(city)),
new Map
), ([con, cities]) => ({ con, cities })
);
Then the HTML part becomes:
<div *ngFor="let item of array ">
<h3>{{item.con}}</h3>
<div *ngFor="let city of item.cities ">
<p>{{city}}</p>
</div>
<hr>
</div>
You can sort your JSON before passing to angular ngFor as bellow,
data = [
{
'con': 'Usa',
'city': 'ny'
},
{
'con': 'Ger',
'city': 'ber'
},
{
'con': 'Usa',
'city': 'la'
}
];
var expectedResult = data.sort(function (a, b) {
return a.con.localeCompare(b.con);
});
console.log(expectedResult)
//OR
// change order as return b.con.localeCompare(a.con);

Two Way Link Using Normalizr

I have a list of regions, which I get from an API. In this list, there are multiple buildings. This will look like this in JS:
const regions = [
{
guid: 'REGION1-GUID',
name: 'Region 1',
buildings: [
{
guid: 'REGION1-BUILDING1-GUID',
name: 'Region 1 Building 1'
},
{
guid: 'REGION1-BUILDING2-GUID',
name: 'Region 1 Building 2'
}
]
},
{
guid: 'REGION2-GUID',
name: 'Region 2',
buildings: [
{
guid: 'REGION2-BUILDING1-GUID',
name: 'Region 2 Building 1'
},
{
guid: 'REGION2-BUIDLING2-GUID',
name: 'Region 2 Building 2'
}
]
}
];
Now I want to normalize this JS Object using normalizr. What I want to do later is to get the region from a building.
So I tried to do the following:
// Define the buildings schema
const building = new schema.Entity('building', {}, { idAttribute: 'guid' });
// Define the regions schema
const region = new schema.Entity(
'regions',
{
buildings: [building]
},
{ idAttribute: 'guid' }
);
const regionList = [region];
const normalizeData = () => {
const normalizedData = normalize(data, regionList);
This does normalize my object, the normalizedData is like this:
{
"entities":{
"building":{
"REGION1-BUILDING1-GUID":{
"guid":"REGION1-BUILDING1-GUID",
"name":"Region 1 Building 1"
},
"REGION1-BUILDING2-GUID":{
"guid":"REGION1-BUILDING2-GUID",
"name":"Region 1 Building 2"
},
"REGION2-BUILDING1-GUID":{
"guid":"REGION2-BUILDING1-GUID",
"name":"Region 2 Building 1"
},
"REGION2-BUIDLING2-GUID":{
"guid":"REGION2-BUIDLING2-GUID",
"name":"Region 2 Building 2"
}
},
"regions":{
"REGION1-GUID":{
"guid":"REGION1-GUID",
"name":"Region 1",
"buildings":[
"REGION1-BUILDING1-GUID",
"REGION1-BUILDING2-GUID"
]
},
"REGION2-GUID":{
"guid":"REGION2-GUID",
"name":"Region 2",
"buildings":[
"REGION2-BUILDING1-GUID",
"REGION2-BUIDLING2-GUID"
]
}
}
},
"result":[
"REGION1-GUID",
"REGION2-GUID"
]
}
But to get the Region of a building i need to iterate over every region and check if the building is contained in the list. I will not get any added value trough the normalization.
It would be perfect if I am able to link in both direction. Every region entitiy has a list of building guids and every building has one region guid.
Is there any way to archieve this in normalizr? What would be the best approach?
Thank you for your help.
I tried some things and found a working solution. I don't know if there is any better approach, but it's very clean code and it's working.
I just had to change the definition of the building entity to:
// Define buildings schema
const building = new schema.Entity(
'building',
{},
{
idAttribute: 'guid',
processStrategy: (entity, parent) => ({ ...entity, regionGuid: parent.guid })
}
);
This will add the property "regionGuid" to the building which holds the guid from the region.

CouchDB sorting by linked doc property

I have the following data:
payment1: {
id: "payment1",
categoryId: "category1"
}
payment2: {
id: "payment2",
categoryId: "category2"
}
payment3: {
id: "payment3",
categoryId: "category2"
}
category1: {
id: "category1",
name: "Food"
}
category2: {
id: "category2",
name: "Leisure"
}
What I need is a view for sorting the payment data by category NAME. Is it possible in CouchDB?
Thanks in advance!
Ivan
What is possible is a bit different from what you want.
Here is the map:
function (o) {
if (o.categoryId) {
emit(o.categoryId);
} else {
emit(o.id);
}
}
You'll call it with /mydb/_design/mydesign/_view/myview?include_docs=true and get:
{"rows":[
{"key":"category1", "doc":{"id":"payment1","categoryId":"category1"},
{"key":"category1", "doc":{"id":"category1","name":"Food"},
{"key":"category2", "doc":{"id":"payment2","categoryId":"category2"},
{"key":"category2", "doc":{"id":"payment3","categoryId":"category2"},
{"key":"category2", "doc":{"id":"category2","name":"Leisure"}
]}
In other words, payments are grouped by category, they are also joined with category's name. However, they are sorted according category ID but not category's name.
What you want would require two different sorts (i.e. "chained map reduce").

How to parse below JSON

How to parse below JSON code in JavaScript where iterators are not identical?
var js= {
'7413_7765': {
availableColorIds: [ '100', '200' ],
listPrice: '$69.00',
marketingMessage: '',
prdId: '7413_7765',
prdName: 'DV by Dolce Vita Archer Sandal',
rating: 0,
salePrice: '$59.99',
styleId: '7765'
},
'0417_2898': {
availableColorIds: [ '249', '203' ],
listPrice: '$24.95',
marketingMessage: '',
prdId: '0417_2898',
prdName: 'AEO Embossed Flip-Flop',
rating: 4.5,
salePrice: '$19.99',
styleId: '2898'
},
prod6169041: {
availableColorIds: [ '001', '013', '800' ],
listPrice: '$89.95',
marketingMessage: '',
prdId: 'prod6169041',
prdName: 'Birkenstock Gizeh Sandal',
rating: 5,
salePrice: '$79.99',
styleId: '7730'
}
}
How can I parse this JSON in JavaScript? I want the values of prdName, listprice, salePrice in JavaScript?
var products = js; // more semantic
for (productId in products){
var product = products[productId];
console.log (product.prdName , product.listprice, product.salePrice);
}
js is an Object, the for (key in instance) iteration moves through the first level object's attributes, in this case 7413_7765, 0417_2898 and prod6169041, this keys are stored in the var productId, so products[productId] will return the value of this attributes.
Note that the "" in object keynames are not necesary.
You have already assigned the JSON to an object js.
You're trying to loop through JavaScript object, as Edorka mentioned iterate it.

Categories