SURVEY DATA
Each object is a survey which can have up to 10 questions and up to 5 different responses.
const allSubmittedSurveysData:{}[] = [
{
surveyGUID:'1234',
q1ID: '0001',
q1Response:'Very Satisfied',
q2ID: '0002',
q2Response:'Very Happy',
q3ID: '0003',
q3Response:'Satisfied',
q4ID: '0004',
q4Response:'Very Satisfied',
q5ID: '0005',
q5Response:'Very Satisfied',
q6ID: '0006',
q6Response:'Very Satisfied',
q7ID: '0007',
q7Response:'Very Satisfied',
q8ID: '0008',
q8Response:'Very Satisfied',
q9ID: '0009',
q9Response:'Very Satisfied',
q10ID: '0010',
q10Response:'Very Satisfied',
},
{
surveyGUID:'1235',
q1ID: '0001',
q1Response:'Satisfied',
q2ID: '0002',
q2Response:'Unhappy',
q3ID: '0003',
q3Response:'Dissatisfied',
q4ID: '0004',
q4Response:'Dissatisfied',
q5ID: '0005',
q5Response:'Very Satisfied',
},
{
surveyGUID:'1236',
q1ID: '0001',
q1Response:'Dissatisfied',
q2ID: '0002',
q2Response:'Neutral',
q3ID: '0003',
q3Response:'Satisfied',
q4ID: '0004',
q4Response:'Very Dissatisfied',
q5ID: '0005',
q5Response:'Very Satisfied',
},
]
let responseCounts: Record<string, any> = {}
allSubmittedSurveysData.forEach((survey: Record<string,any>) => {
Object.keys(survey).forEach(key => {
if(key!=='surveyGUID') {
let questionKey = key.replace('Response', 'ID')
let responseKey= key.replace('ID','Response')
if(!Object.keys(responseCounts).includes(survey[questionKey])){
responseCounts[survey[questionKey]]={}
}
if(!Object.keys(responseCounts[survey[questionKey]]).includes(survey[responseKey])){
responseCounts[survey[questionKey]][survey[responseKey]]= 1
} else{
++responseCounts[survey[questionKey]][survey[responseKey]]
}
}
})
})
Example expected output:
responseCounts= {
0001:{
Very Satisfied:1,
Satisfied:1,
Dissatisfied:1
},
0002:{...},
0003:{...},
etc
}
I'm making a 'responseCounts' object which will have an object for each question ID. Within each question ID object I've made the response the key and in the first instance if the "responseCounts'" keys does not include the response, the key is made and given 1 as the value. In the subsequent loop I'm expecting it to add one if the response is already a key in the object and the response is given again. The if condition is working as expected. The else is taking the value and doubling it instead of adding one each time the condition is met.
You are actually adding it twice, once for the ID key and once for the Response key.
Compare your version
if(key!=='surveyGUID') {
let questionKey = key.replace('Response', 'ID')
let responseKey= key.replace('ID','Response')
with this:
if(key!=='surveyGUID' && key.includes('Response')) {
let questionKey = key.replace('Response', 'ID')
let responseKey= key
Related
I am pulling backend data to my application, but i want the user to be able to select which keys they want to see. So i have been trying to build a way for them to generate an array of strings and have that be compared to each object in the array and output the new array of objects with each key excluded.
Here is the Filter array:
const filterData =
[
'TestOne',
'TestTwo',
]
Here is the array of objects:
const data = [
{
_id: "62ec2f1084c7f48175a9cb4a",
Date: "2022-08-04T15:41:37.567Z",
facilityId: "62e5a9fd45f2646fc7361fa3",
userId: "62e16d390f4685e4fdb6a288",
formData: {
Date: "2022-08-04T15:41:37.567Z",
TestOne: 60002,
TestTwo: 19998,
TestThree: 102,
TestFour: "True"
},
},
{
_id: "62ec2f1c84c7f48175a9cb58",
Date: "2022-08-04T15:41:52.932Z",
facilityId: "62e5a9fd45f2646fc7361fa3",
userId: "62e16d390f4685e4fdb6a288",
formData: {
Date: "2022-08-04T15:41:52.932Z",
TestOne: 60003,
TestTwo: 19997,
TestThree: 103,
TestFour: "True"
},
},
]
I want to build a function that takes the data.formData and filters out any keys that are not included in the filterData. I am having a hard time figuring out what exactly needs done to acheive this. If anyone could help id greatly appreciate it.
----EDIT----
Here is something of a process that i have thought of but it returns errors and cant really think of why.
const formObject =
datas.length > 0 &&
datas.map((data, i) => {
const filterData = ['TestOne', 'TestTwo']
filterData.map((filter) => {
delete data.formData[filter]
})
})
This function gives me errors of Uncaught TypeError: Cannot delete property 'TestThree' of #<Object>, ive tried making a new instance of datas but it doesnt work
I would do it this way:
const result = data.map(x => {
for (const [key, value] of Object.entries(x.formData)) {
if (!filterData.includes(key)) {
delete x.formData[key];
}
}
return x;
})
Hope this helps
The key highlights to this function are:
Before the first loop, the array is cloned✥ then each object is skimmed over to find "formData". Since the actual keys are known, I'm going on the logical assumption that the object that has them is known as well -- hence the second parameter path.
Object.keys(obj['formData']) = ["Date", "TestOne", "TestTwo", "TestThree", "TestFour"] :
Figure I
function filterData(array, path, ...keys) {
let clone = structuredClone(array);
for (let obj of clone) {
Object.keys(obj[path]).flatMap(key =>
//... obj[path] = [ {{["formData"]}}...
//... ["Date", "TestOne", "TestTwo", "TestThree", "TestFour"]
On the second loop, the keys form the first loop is checked vs. the third parameter ...keys, a rest parameter that consists of one or more keys to filter out. The if condition has been reversed with ! operator:
Figure II
if (![...keys].includes(key)) {
return [];
}
return delete obj[path][key];
✥The TypeError sounds like the object is frozen so by cloning the array you can freely work on the clone.
const data = [{
_id: "62ec2f1084c7f48175a9cb4a",
Date: "2022-08-04T15:41:37.567Z",
facilityId: "62e5a9fd45f2646fc7361fa3",
userId: "62e16d390f4685e4fdb6a288",
formData: {
Date: "2022-08-04T15:41:37.567Z",
TestOne: 60002,
TestTwo: 19998,
TestThree: 102,
TestFour: "True"
}
}, {
_id: "62ec2f1c84c7f48175a9cb58",
Date: "2022-08-04T15:41:52.932Z",
facilityId: "62e5a9fd45f2646fc7361fa3",
userId: "62e16d390f4685e4fdb6a288",
formData: {
Date: "2022-08-04T15:41:52.932Z",
TestOne: 60003,
TestTwo: 19997,
TestThree: 103,
TestFour: "True"
}
}];
/**
* Find any given number of keys and remove them
* #param {array<object>} array - An array of objects
* #param {string} path - Name of the key if the target object is one
* level down. (todo: recursive algorithm to dig deeper)
* #param {string/array<string>} keys - List of keys to filter out
* #return {array<object>} The array sans filtered keys
*/
function filterData(array, path, ...keys) {
let clone = structuredClone(array);
for (let obj of clone) {
Object.keys(obj[path]).flatMap(key => {
if (![...keys].includes(key)) {
return [];
}
return delete obj[path][key];
});
}
return clone;
}
let x = filterData(data, "formData", "Date", "TestFour");
console.log(x);
I have an array which contains some java script objects and I am using ejs for display data but the problem is - that I have to filter that data in the bases of req.params.id and want to next 2 data objects..! after filtering data -- please help
my code is -
app.get("/:id", (req, res) => {
const requestParams = _.lowerCase(req.params.id);
let obj = blogData.find((o) => o.heading >= "Yoga-During-COVID");
console.log(obj);
blogData.forEach(function (post) {
const storedTitel = _.lowerCase(post.heading);
if (storedTitel === requestParams) {
res.render("blogfullDetail", {
date: post.date,
heading: post.heading,
subheading: post.subheading,
discription: post.discription,
discription2: post.discription2,
author: post.author,
authorImage: post.authorImage,
mainImg: post.mainImg,
});
}
});
});
data file -
Use a combination of findIndex and slice. findIndex returns the index of the matching element and slice returns a sub-array from that index to a computed higher index...
let blogData = [{
id: 1,
title: 'yoga is good'
},
{
id: 32,
title: 'yoga helps you stretch'
},
{
id: 12,
title: 'covid yoga is good too'
},
{
id: 41,
title: 'no such thing as too much yoga'
},
{
id: 57,
title: 'is hot yoga too hot'
}
];
// say you need the post about covid...
let targetTitle = 'covid yoga is good too';
let index = blogData.findIndex(p => p.title === targetTitle);
// with the index, answer a slice of the blogs
// starting at that index, ending 3 later
let posts = blogData.slice(index, index + 3);
console.log(posts)
Looking for a way to merge Javascript Object keys inside array, only on matching Ids. Should i use Map? or flatmap?
I have
const districtList =[
{ id:'1234blah', companyId:'09871345', districtName:'abc1' },
{ id:'2341blah', companyId:'87134590', districtName:'abc2' },
{ id:'3412blah', companyId:'09134587', districtName:'abc3' },
]
and
const companyList =[
{id:'09871345', companyName:'CompanyOne', info:'some' },
{id:'87134590', companyName:'CompanyTwo', info:'stuff' },
{id:'09134587', companyName:'CompanyThree', info:'todo' },
]
But what i want is the data from the company array inside the district array, to get the missing company name, and other info.
const improvedDistrictList =[
{ id:'1234blah', companyId:'09871345', districtName:'abc1', companyName:'CompanyOne', info:'some' },
{ id:'2341blah', companyId:'87134590', districtName:'abc2', companyName:'CompanyTwo', info:'stuff' },
{ id:'3412blah', companyId:'09134587', districtName:'abc3', companyName:'CompanyThree', info:'todo' },
]
I would map through the district list, find a corresponding company for each one based on the companyId and then just add more fields to the new array with one caveat: it looks like your companyList array may or may not contain companyName. As such:
const districtList =[
{id:'1234blah',companyId:'09871345', districtName:'abc1'},
{id:'2341blah',companyId:'87134590', districtName:'abc2'},
{id:'3412blah',companyId:'09134587', districtName:'abc3'},
]
const companyList =[
{id:'09871345',companyName:'CompanyOne', info:'some'},
{id:'87134590',companyId:'CompanyTwo', info:'stuff'},
{id:'09134587',companyId:'CompanyThree', info:'todo'},
]
const result = districtList.map(item => {
const company = companyList.find(c => c.id === item.companyId);
return {...item, [company.companyName ? 'companyName' : 'companyId']: company.companyName ? company.companyName : company.companyId, info: company.info }
})
console.log(result)
Also, as pointed out in the comments, you won't end up with 2 companyId keys in the resulting array as the latter will override the former.
this way...
const districtList =[
{ id:'1234blah', companyId:'09871345', districtName:'abc1' },
{ id:'2341blah', companyId:'87134590', districtName:'abc2' },
{ id:'3412blah', companyId:'09134587', districtName:'abc3' },
]
const companyList =[
{id:'09871345', companyName:'CompanyOne', info:'some' },
{id:'87134590', companyName:'CompanyTwo', info:'stuff' },
{id:'09134587', companyName:'CompanyThree', info:'todo' },
]
const improvedDistrictList = companyList.map(cl=>
({...cl,...districtList.find(x=>x.companyId===cl.id)}))
console.log( improvedDistrictList )
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have a nested JSON and want to end up with the result array, how is this possible? Any tips on how i can accomplish this? Do i need to use a nester for in/of loop? Higher order functions etc? I am new to nested objects, any tip or good reference will be appreaciated!
// const db shows the desired result once db.save() is called. I want it
to include the Date, Symbols (USD etc.) and the value of it - all wrapped inside their own object
const db = [
{ Date: '1999-01-05', AUD: 1.8944, SEK: 9.4025, USD: 1.179 },
{ Date: '1999-01-06', AUD: 1.882, SEK: 9.305, USD: 1.1743 },
];
// the json that i recieve upon fetching
const json = {
rates: {
'1999-01-08': {
AUD: 1.8406,
SEK: 9.165,
USD: 1.1659,
},
'1999-01-06': {
AUD: 1.882,
SEK: 9.305,
USD: 1.1743,
},
'1999-01-07': {
AUD: 1.8474,
SEK: 9.18,
USD: 1.1632,
},
'1999-01-05': {
AUD: 1.8944,
SEK: 9.4025,
USD: 1.179,
},
},
start_at: '1999-01-05',
base: 'EUR',
end_at: '1999-01-10',
};
Here's a solution using nested for loops and Object.entires to get a key/value pair from your object. It creates an array of objects just like your desired result. (Not in the exact order, as Javascript doesn't care for keeping objects sorted).
function save(data) {
const db = []
for (const [key, value] of Object.entries(data.rates)) {
rate = { 'Date': key }
for (const [_key, _value] of Object.entries(value)) {
rate[_key] = _value
}
db.push(rate)
}
return db
}
Usage; in your posted example, would be:
db = save(json)
Thanks for the answer, i didn't get it to work as i probably messed something up or explained poorly, apologise. But seeing you using nested for loop helped me figure out this approach which resulted in every currency and exchange rate from a specific date to be in one object with only key values.
const db = [];
for (const prop in json.rates) {
Object.keys(json.rates[prop]).forEach((element) => {
const obj = {
date: prop,
symbol: element,
rate: json.rates[prop][element],
base: json.base,
};
db.push(obj);
});
}
console.log(db);
enter code here
enter code here
I have two values I need to match as you can see in the picture below:
I tried something like this:
const index = state.locks.users.findIndex(
stateUser => stateUser._id === action.payload.customerPayload.accessid
But I’m getting the error:
findIndex of undefined.
And I guess that’s because of locks being an array.
But I’m really uncertain how to fix this issue. Should I have multiple findIndexes? One for the lock and one for to match the users?
Thanks for reading my post. And I appreciate all the help I can get.
The code snippet should be
let itemIndex = -1;
state.locks.map((lock) => {
lock.users.findIndex(...)
});
Assuming state is an object containing locks array.
My suggestion to you is do a double for loop (as you've already figured) to get the user object that you need.
Consider the following snippet (adjust to your data structure):
let state = {
locks: [
{
users: [
{ _id: '123' },
{ _id: '456' }
]
},
{
users: [
{ _id: '678' },
{ _id: '789' }
]
},
]
};
function getUserObjByID(stateObj, userID) {
for (let usersObject of state.locks) {
for (let user of usersObject.users) {
if (user._id === userID) {
return user;
}
}
}
}
let myObj = getUserObjByID(state, '678');
console.log(myObj);
So it works now. What I had to do with my reducer was this:
case 'REMOVE_USER':
return {
...state,
locks: state.locks.map(lock => {
return {
...lock,
users: lock.users
? lock.users.filter(
user => user._id != action.payload.customerPayload.accessid
)
: []
}
})
}