Thanks for taking a look here. I'm working with an API, and need to change the format of the data. Here's an example of the return data:
data: [
{
status: "planned work",
name: "123"
},
{
status: "all good",
name: "nqr"
}
];
Each train line has a name like "123" or "nqr", and I want to split each train into their own objects so that it would look something like this:
data: [
{
status: "planned work",
name: "1"
},
{
status: "planned work",
name: "2"
},
{
status: "planned work",
name: "3"
},
{
status: "all good",
name: "n"
},
{
status: "all good",
name: "q"
},
{
status: "all good",
name: "r"
}
];
I have some working code which splits the name and uses nested .forEach loops to push items to an array. Working code:
function formatLinesData(lines) {
var trains = [];
lines.forEach( line => {
line.name.split("").forEach(train => {
trains.push({name: train, status: line.status});
});
});
return trains;
}
Is there a way to accomplish this without the nested loops? Looking for an elegant solution if you have one.
Thanks
You might do as follows;
var data = [
{
status: "planned work",
name: "123"
},
{
status: "all good",
name: "nqr"
}
],
newData = [].concat(...data.map(o => o.name.split("").map(c => ({status: o.status, name: c}))));
console.log(newData);
You can use reduce - initialize it with an empty array, and iterate over the data
array using your logic.
data.reduce((prev,curr) => {
for (let i=0; i<curr.name.length; i++) {
prev.push({ name : curr.name[i], status : curr.status});
}
return prev;
},[]);
Related
I have a state variable projects which should store a dictionary of arrays, where the key is id of the organisation that owns the project, and the array consists of objects storing information about the project. For example:
{
orgId123: [
project1: {
name: "my cool project",
status: "submitted"
},
projectAwesome: {
name: "Stan's project",
status: "draft"
}
],
orgUSA: [
newProj234: {
name: "another great project",
status: "submitted"
}
]
}
I try to get a list of all organisation IDs using Objects.keys(projects), however that returns an empty array.
I suspect that somehow my projects variable is structured wrongly. When I console.log the contents of projects, I get:
Notice how the root level object says just {}.
When I tried to re-create what the projects variable should look like and logged that, I saw a slightly different output:
In this manually created object, the root-level object is shown as {orgId1}: Array(1) instead of the previously-shown {} (on the actual object).
What does this say about how the object is structured and why can I not get a list of keys from the first object using Object.keys()?
For context, I create the original variable using the following code:
async function fetchProjects() {
// Load list of organisations that the user is a member of
const organisationsSnapshot = await getDocs(query(
collection(db, 'organisations'),
where(`members.${user.uid}`, '!=', null)
))
const organisations = organisationsSnapshot.docs.map(organisationSnap => ({
...organisationSnap.data(),
id: organisationSnap.id
}))
// Load list of projects for each organisation the user is a member of
const projectsDict = {}
organisations.forEach(async (organisation) => {
const projectsQuery = query(collection(db, `organisations/${organisation.id}/projects`))
const projectsSnap = await getDocs(projectsQuery)
projectsDict[organisation.id] = projectsSnap.docs.map(projectSnap => ({
...projectSnap.data(),
id: projectSnap.id
}))
})
setProjects(projectsDict)
}
You cannot have an array of key:values. You should wrap it in {}.
[ key1: value1, key2: value2, ] //Unexpected Token
[ { key1: value1 }, { key2: value2 }, ] //Good to go
So instead of:
{
orgId123: [
project1: {
name: "my cool project",
status: "submitted"
},
projectAwesome: {
name: "Stan's project",
status: "draft"
}
],
orgUSA: [
newProj234: {
name: "another great project",
status: "submitted"
}
]
}
You should have:
{
orgId123: [
{
project1: {
name: "my cool project",
status: "submitted"
}
},
{
projectAwesome: {
name: "Stan's project",
status: "draft"
}
}
],
orgUSA: [
{
newProj234: {
name: "another great project",
status: "submitted"
}
}
]
}
OR
{
orgId123: {
project1: {
name: "my cool project",
status: "submitted"
},
projectAwesome: {
name: "Stan's project",
status: "draft"
}
},
orgUSA: {
newProj234: {
name: "another great project",
status: "submitted"
}
}
}
Honestly, I would structure your projects as follows:
const organisations = [{
orgId: "orgId123",
projects: [{
projectId: "project1",
name: "my cool project",
status: "submitted"
}, {
projectId: "projectAwesome",
name: "Stan's project",
status: "draft"
}]
},
{
orgId: "orgUSA",
projects: [{
projectId: "newProj234",
name: "another great project",
status: "submitted"
}]
}
]
//This way, organisations is an array of organisations,
//which is an object that has orgId, projects which is an array of its projects.
//It will be much more intuitive to work with while iterating over it.
//Such as if you need to display all the orgIds,
console.log("Organisation IDs:")
for (const org of organisations) {
console.log(org.orgId)
}
console.log("=================");
//If you need all project IDs and names:
console.log("Projects:")
for (const org of organisations) {
console.log(`Organisation ${org.orgId} has the following projects:`)
for (const proj of org.projects) {
console.log(`Project ID ${proj.projectId}: ${proj.name}`)
}
console.log("=================");
}
console.log("=================");
I have this JSON generated from external (Reviews-io) script:
https://widget.reviews.co.uk/rich-snippet/dist.js
richSnippet({
store: "www.storedigital.local",
sku:"6647;6647_5;6647_4;6647_3;6647_11;6647_10;6647_2;6647_1;6647_9;6647_8;6647_7;6647_6",
data:{
"url": "store.stg.gsd.local/1/silla-replica-eames.html",
"description": ``,
"mpn": "6647",
"offers" :[{
"#type":"Offer",
"availability": "http://schema.org/InStock",
"price": "559",
"priceCurrency": "MXN",
"url": "https://store.stg.gsd.localx/1/silla-replica-eames.html",
"priceValidUntil": "2022-05-26",
}],
"brand": {
"#type": "Brand",
"name": "Not Available",
}
}
})
I need to get all the string of numbers in "sku", and then put them in another variable as same format (6647; 6647_1; 6647_2)
I try to get the numbers using this JS but doesn't works
var skucollection = JSON.parse(richSnippet, function (key, value) {
if (key == "sku") {
return new Sku(value);
} else {
return value;
}
});
Can you help me check what I am doing wrong, to get this sku's value string, please?
JSON.parse is not too much? ,handle it as it is internally (a JSON indeed)
var richSnippet = {
store: 'www.storedigital.local',
sku: '6647;6647_5;6647_4;6647_3;6647_11;6647_10;6647_2;6647_1;6647_9;6647_8;6647_7;6647_6',
algomas: [],
data: {
url: 'store.stg.gsd.local/1/silla-replica-eames.html',
description: ``,
mpn: '6647',
offers: [
{
'#type': 'Offer',
availability: 'http://schema.org/InStock',
price: '559',
priceCurrency: 'MXN',
url: 'https://store.stg.gsd.localx/1/silla-replica-eames.html',
priceValidUntil: '2022-05-26',
},
],
brand: {
'#type': 'Brand',
name: 'Not Available',
},
},
};
var test;
Object.keys(richSnippet).forEach((key) => {
if (key == 'sku') {
test = richSnippet[key];
}
});
console.log('test', test);
I am trying to pull an array from a different collection using collection2. I have been able to do this with objects using the following example for users:
users: {
type: String,
label: "Inspector",
optional: true,
autoform: {
firstOption: 'Choose an Inspector',
options: function() {
return Meteor.users.find({}, {
sort: {
profile: 1,
firstName: 1
}
}).map(function(c) {
return {
label: c.profile.firstName + " " + c.profile.lastName,
value: c._id
};
});
}
}
},
I would like to do the same but for an array of objects. Here is what the source data looks like:
{
"_id": "xDkso4FXHt63K7evG",
"AboveGroundSections": [{
"sectionName": "one"
}, {
"sectionName": "two"
}],
"AboveGroundItems": [{
"itemSection": "one",
"itemDescription": "dfgsdfg",
"itemCode": "dsfgsdg"
}, {
"itemSection": "two",
"itemDescription": "sdfgsdfg",
"itemCode": "sdfgsdgfsd"
}]
}
Here is what my function looks like:
agSection: {
type: String,
optional: true,
autoform: {
firstOption: 'Select A Section Type',
options: function() {
return TemplateData.find({}, {
sort: {
AboveGroundSections: 1,
sectionName: [0]
}
}).map(function(c) {
return {
label: c.AboveGroundSections.sectionName,
value: c.AboveGroundSections.sectionName
}
});
}
}
},
I know this, it's just not pulling the data for me. I am sure, I am just missing something small. I am trying to pull all objects within the AboveGroundSection array.
Your .map() is iterating over the set of documents but not over the arrays inside each document. Also I don't think your sorting is going to work the way you hope because of the inner nesting.
Try:
agSection: {
type: String,
optional: true,
autoform: {
firstOption: 'Select A Section Type',
options() {
let opt = [];
TemplateData.find().forEach(c => {
c.AboveGroundSections.forEach(s => { opt.push(s.sectionName) });
});
return opt.sort().map(o => { return { label: o, value: o } });
}
}
},
Also if your AboveGroundSections array only has a single key per element then you can simplify:
"AboveGroundSections": [
{ "sectionName": "one" },
{ "sectionName": "two" }
]
To:
"AboveGroundSections": [
"one",
"two"
]
I googled some examples and tutorials but couldn't find any clear example for my case.
I get a JSON response from my server like this:
var heroes = [
{
id: 5,
name: 'Batman',
realName: 'Bruce Wayne',
equipments: [
{
type: 'boomarang',
name: 'Batarang',
},
{
type: 'cloak',
name: 'Bat Cloak',
},
{
type: 'bolas',
name: 'Bat-Bolas',
}
]
},
{
id: 6,
name: 'Cat Woman',
realName: 'Selina Kyle',
equipments: [
{
type: 'car',
name: 'Cat-illac',
},
{
type: 'bolas',
name: 'Cat-Bolas',
}
]
}
];
I would like to query for example: "get heroes with equipment type of bolas"
and It should return both hero objects in an array.
I know it is not right but what I am trying to do is to form a map function like this:
function myMapFunction(doc) {
if(doc.equipments.length > 0) {
emit(doc.equipment.type);
}
}
db.query(myMapFunction, {
key: 'bolas',
include_docs: true
}).then(function(result) {
console.log(result);
}).catch(function(err) {
// handle errors
});
Is it possible? If not what alternatives do I have?
P.S: I also checked LokiJS and underscoreDB. However PouchDB looks more sophisticated and capable of such query.
Thank you guys in advance
Your map function should be:
function myMapFunction(doc) {
doc.equipments.forEach(function (equipment) {
emit(equipment.type);
});
}
Then to query, you use {key: 'bolas'}:
db.query(myMapFunction, {
key: 'bolas',
include_docs: true
}).then(function (result) {
// got result
});
Then your result will look like:
{
"total_rows": 5,
"offset": 0,
"rows": [
{
"doc": ...,
"key": "bolas",
"id": ...,
"value": null
},
{
"doc": ...,
"key": "bolas",
"id": ...,
"value": null
}
]
}
Also be sure to create an index first! Details are in the PouchDB map/reduce guide :)
I wish I could give this a more descriptive title, but I don't really know the name of what I am trying to do. I have a JSON list in angular that looks like this:
$scope.users =
{
// list name and the "title" must be the same
Guest:
{
title: 'Guest',
list:
[
{ id: "0", name: "Stephen" },
{ id: "1", name: "Mitch"},
{ id: "2", name: "Nate"},
{ id: "3", name: "Rob" },
{ id: "4", name: "Capt. Jack"},
{ id: "5", name: "Herman" }
]
},
Admin:
{
title: 'Admin',
list:
[]
}
};
And I need to dynamically evaluate a string (either "Guest" or "Admin" or any other user-group that hasn't been created) in order to move a user from one user-group to another.
The function I am working with looks like:
$scope.moveUser = function(fromId, toId, index) {
scope.users.toId.list.push(scope.users.fromId.list[index]);
scope.users.fromId.list.splice(index, 1);
};
with "fromId" and "toId" being strings that evaluate to the name of a user-group ("Admin" or "Guest"). Right now, the function is trying to find a JSON field called "toId" and errors when it can't find any. How would I evaluate the string first so that if the toId == "Guest" and the fromId == "Admin", my function becomes:
scope.users.Guest.list.push(scope.users.Admin.list[index]);
scope.users.Admin.list.splice(index, 1);
change your $scope.moveUser function to
$scope.moveUser = function(fromId, toId, index) {
$scope.users[toId].list.push($scope.users[fromId].list[index]);
$scope.users[fromId].list.splice(index, 1);}
it is really work
If I understand correctly:
$scope.moveUser = function(fromId, toId, index) {
if (users.hasOwnProperty(fromId) && users.hasOwnProperty(toId)) {
scope.users.toId.list.push(scope.users.fromId.list[index]);
scope.users.fromId.list.splice(index, 1);
return true;
} else {
return false;
}
};