Stack Overflow! This is my very first.
So, say for example I have the following array:
[
{
"question1": "Apple",
"question2": 5,
"question3": "Item 1"
},
{
"question1": "Apple",
"question2": 4,
"question3": "Item 2"
},
{
"question1": "Orange",
"question2": 4,
"question3": "Item 2"
}
]
Each object represents a respondent's answers to each question from a survey, which means the array above has a total of 3 responses.
What I want is to count the answers of each question, like how many in a multiple choice question chose X answer and so on.
The following output should look like this for a single question:
[
{
"answer": "Apple",
"count": 2,
},
{
"answer": "Orange",
"count": 1,
}
]
Which means according to the example above I'll need total of 3 arrays (because total 3 questions) of counted answers.
Is there any way to achieve this? My goal here is to use ChartJS in React to display charts of the responses of each question.
Final output for a single chart (of a single question, say question1):
[
{
"answer": "Apple",
"count": 2,
},
{
"answer": "Orange",
"count": 1,
}
]
This outputs an array of arrays of objects, instead of multiple array variables of objects. Since JavaScript objects preserve insertion order, you don't need to worry about the questions being out of order, assuming they're already in the proper order.
const data = [{question1:"Apple",question2:5,question3:"Item 1"},{question1:"Apple",question2:4,question3:"Item 2"},{question1:"Orange",question2:4,question3:"Item 2"}];
const newData = Object.values(data.reduce((acc, qna) => {
for (const [question, answer] of Object.entries(qna)) {
acc[question] = acc[question] ?? {};
acc[question][answer] = (acc[question][answer] ?? 0) + 1;
}
return acc;
}, {}))
.map((answerCount) => Object.entries(answerCount)
.map(([answer, count]) => ({ answer, count }))
);
console.log(newData);
Related
I am building a Blog app and I am trying to get results but it is showing duplicate results, I am trying to remove the duplicate results from the array.
But the problem is there are two key and values in each dict inside array, One is unique and other can be same so I am trying to distinct based on same array, It worked But the other key and value pair (which is unique) is not attaching with the other pair.
response which is returning from db
[
{
"id": 2,
"name": "user_1"
},
{
"id": 3,
"name": "user_3"
},
{
"id": 4,
"name": "user_3"
}
]
App.js
function App() {
const [blogs, setBlogs] = useState([]);
axios.get("retract_blogs/").then((res) => {
// Here I also want to attach "id"
setBlogs({[...new Set(res.data.data.map(x => x.name))]})
}
return(
<div>
{
blogs.map((user) =>
<div>
{user.name}
// Here I wamt to show ID
// {user.id}
</div>
}
</div>
)
}
I want to add id with x.username, I also tried using
setBlogs({data:[...new Set(res.data.data.map(x => x.name, x.id))]})
But it showed
x is not defined
But I am trying to add both name and id, and remove duplicates based on name not id.
I have tried many times but it is still not working.
To keep the id of the last occurence you can create a Map of the array keyed by name and then convert back to an array using the iterator returned by Map.values(). This works by overwriting earlier entries in the Map with the same name.
const users = [{ "id": 2, "name": "user_1" }, { "id": 3, "name": "user_3" }, { "id": 4, "name": "user_3" }];
const result = [...new Map(users.map((user) => [user.name, user])).values()];
console.log(result);
// [ { id: 2, name: 'user_1' }, { id: 4, name: 'user_3' } ]
If you instead want to keep the id of the first occurence of a name you can use a slightly modified 'group by' grouping into an object by name (here in a reduce() call, but it could easily be done in a standard loop as well) before taking the Object.values. This works by only setting the accumulator[name] property if it doesn't already exist, here using logical nullish assignment (??=)
const users = [{ "id": 2, "name": "user_1" }, { "id": 3, "name": "user_3" }, { "id": 4, "name": "user_3" }];
const result = Object.values(users.reduce((a, c) => (a[c.name] ??= c, a), {}));
console.log(result);
// [ { id: 2, name: 'user_1' }, { id: 3, name: 'user_3' } ]
I have a question about creating JavaScript arrays. Here's what I want to do.
I have two arrays. Each array has object(s) in them.
The first array has exactly 5 objects, each with a key/value pair (id/name). This array will ALWAYS have 5 objects.
Here's what it looks like...
[
{
"id": 1,
"name": "AnalyticalAdmin"
},
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
},
{
"id": 5,
"name": "SystemAdministrator"
},
{
"id": 6,
"name": "CaseworkSTRTechLeader"
}
]
The second array will have either...
no objects,
4 or less objects,
exactly 5 objects.
In the example below, the second array only has one of the 5 objects in the first array...
[
{
"id": 4,
"name": "AdminReviewer"
}
]
I need to create a third array that has exactly 5 boolean values that are determined by comparing the first two arrays.
For example, based on the first two arrays above, the third array would be...
[false, false, true, false, false]
The reason the third array would look like this is because "AdminReviewer" is the third object in the first array, so the third boolean value in the third array would be true (since it's a match).
But because the first, second, fourth, and fifth objects in the first array do not exist in the second array, their boolean equivalent in the third array would be false.
To accomplish this, I know I need to either do a compare function on the first two arrays to create the third array (of booleans) or I need to run a for loop on the first array, comparing it to the second array to create the third array (of booleans).
Can anyone help me with this?
This could be done as follows:
const filterStrings = filterArray.map(o => JSON.stringify(o));
const result = baseArray.map(o => filterStrings.includes(JSON.stringify(o)));
Please take a look at below runnable code and see how it works.
const baseArray = [
{
"id": 1,
"name": "AnalyticalAdmin"
},
{
"id": 2,
"name": "Analyst"
},
{
"id": 4,
"name": "AdminReviewer"
},
{
"id": 5,
"name": "SystemAdministrator"
},
{
"id": 6,
"name": "CaseworkSTRTechLeader"
}
];
const filterArray = [
{
"id": 4,
"name": "AdminReviewer"
}
];
const filterStrings = filterArray.map(o => JSON.stringify(o));
const result = baseArray.map(o => filterStrings.includes(JSON.stringify(o)));
console.log(result);
I have a nested array that looks like this:
[["Organisation","ID","Name"],["ACME","123456","Bart Simpson"],["ACME","654321","Ned Flanders"],["ACME","1234","Edna Kabappel"],["Yahoogle","666666","Bon Scott"],["Yahoogle","99999","Neil Young"],["Yahoogle","111111","Shania Twain"]]
The first value in each array is the name of an organisation that an ID and name can belong to.
I am trying to find the simplest way to group all instances where an ID and name belong to the same company, under one 'key'.
So the above would result in something like this:
{
"ACME": [
{
"ID": 123456,
"Name": "Bart Simpson"
},
{
"ID": 654321,
"Name": "Ned Flanders"
},
{
"ID": 1234,
"Name": "Edna Kabappel"
}
],
"Yahoogle": [
{
"ID": 666666,
"Name": "Bon Scott"
},
{
"ID": 99999,
"Name": "Neil Young"
},
{
"ID": 111111,
"Name": "Shania Twain"
}
]
}
I have been playing around with for loops but I'm ending up with many many lines of code, trying to detect when the company name is different from the previous, and getting into a real mess with things.
I have searched a lot here trying to find something similar but have not had any luck.
I have only just started coding again for person interest after about 18 years and I'm very novice again.
Thank you in advance for any assistance.
lot of solutions to arrive at same result, one using lambda and reduce: this is a generic solution, just adapt the output push to build your final json.
const datas = [
["Organisation", "ID", "Name"],
["ACME", "123456", "Bart Simpson"],
["ACME", "654321", "Ned Flanders"],
["ACME", "1234", "Edna Kabappel"],
["Yahoogle", "666666", "Bon Scott"],
["Yahoogle", "99999", "Neil Young"],
["Yahoogle", "111111", "Shania Twain"]
];
const titles = datas.shift()
const groupBy = (x,f)=>x.reduce((a,b)=>((a[f(b)]||=[])
.push({[titles[1]]:b[1], [titles[2]]:b[2]}),a),{});
const result = groupBy(datas, v => v[0])
console.log(result)
Using Array.reduce. Please check if this works for you. In the below approach ID and Name is hard coded. You can try writing a generic dynamic approach which handle any number of params like ID, Name, Age etc.
const myArray = [
["Organisation", "ID", "Name"],
["ACME", "123456", "Bart Simpson"],
["ACME", "654321", "Ned Flanders"],
["ACME", "1234", "Edna Kabappel"],
["Yahoogle", "666666", "Bon Scott"],
["Yahoogle", "99999", "Neil Young"],
["Yahoogle", "111111", "Shania Twain"]
];
const obj = myArray.reduce((acc, value, index) => {
if (index === 0) return acc;
const key = value[0];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push({
ID: value[1],
Name: value[2]
});
return acc;
}, {});
console.log(obj);
In order to achieve what you want, you can follow below steps:
Create an object to store your result.
While you are running the loop you have to check whether name of the organization exists as a key in the object and add it if it does not, initializing it to an empty array. Then push the result you want to store into that array.
Below is a sample implementation, assuming your data is stored in data:
var result = {};
for(var i=1; i < data.length; i++){
if(!result.hasOwnProperty(data[i][0])){
result[data[i][0]] = [];
}
result[data[i][0]].push({ "ID": data[i][1], "Name": data[i][2]});
}
I have a question about manipulating data in an associative array.
What I want to do
I want to verify if an order exists in sellingItems.
Background(why?)
I want to check if there is an order to return the number of products in stock as a response.
Question
I want to check if a specific data (order) exists in an associative array and calculate the inventory count.
public calculateStockQuantity(itemInstances) {
const stockQuantity = //We want to count the number of items in stock. In this case, we want it to be 2 (calculated based on whether the data exists in sellingItem.order or not).)
return stockQuantity;
}
Associative array of targets
//There are three itemInstances for one product because the number of products sold is three.
itemInstances =
[
{
"id": "1",
"sellingItem": [
{
"id": 1,
"price": 3000,
"orderedItem": [
{
"id": 1
"ordered_at": "2021-04-01 10:00:00"
}
]
}
]
},
{
"id": "2",
"sellingItem": [
{
"id": 2,
"price": 3000,
"orderedItem": []
}
]
},
{
"id": "2",
"sellingItem": [
{
"id": 2,
"price": 3000,
"orderedItem": []
}
]
}
]
Sorry for asking like a newbie.
Please check if this is something you are looking for, assuming if orderedItem array is empty then that sellingItem will be counted as in stock
let count = itemInstances.filter(({sellingItem : [{ orderedItem }]}) => orderedItem.length === 0).length;
console.log(count); //return 2 based on question data
I am trying to use Lodash to filter an array of objects based on a match of id's, this is what I have tried:
var team = _.find(this.teams, { 'id': this.newSchedule.team});
_.filter(this.yards, function(yard) {
return _.find(team.yards, { id: yard.id });
});
yards data:
[ { "id": 1, "name": "Test" },{ "id": 2, "name": "Test 2" } ]
team data:
[ { "id": 1, "name": "Team 1", "yards": [{ "id": 1, "name" }] ]
I want this.yards to show the yards based on the yard id from a selected team.
Its hard to understand what you mean, does the yard id match the team id?
If so it sounds like what you need to do is first find the team with the same id then grab that teams yards. Therefore I would use the map function twice:
const result = this
.yards
.map(y => team.find(t => t.id === y.id)) // join with the right team
.map(t => t.yards) // reduce to that teams yards
As team is an array, you need to iterate it before doing the _.find on an individual element in that array. It doesn't help that you called your variable team (singular). teams would make more sense.
Here is how you would change your lodash code:
var yards = [ { id: 1, name: "Test" },{ id: 2, name: "Test 2" } ],
teams = [ { id: 1, name: "Team 1", yards: [{ id: 1, name: "Missing string" }] } ]
result = _.filter(this.yards, function(yard) {
return _.some(this.teams, function(team) {
return _.find(team.yards, { id: yard.id });
});
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
So this returns the yards that are related to at least one team.