Failed to console unique names from JSON array - javascript

I have a JSON array having hundreds of objects where each JSON object having name and hobbies property.
Below is the JSON structure:
const data = [
{
name:'Paul',
hobbies: ['Football','Reading']
},
{
name:'Riya',
hobbies: ['Singing','Dancing']
},
{
name:'Jack',
hobbies: ['Gaming']
}
]
So here if I will iterate through this data it will give me same name multiple times wherever multiple hobbies are present.So if I am console it result would be
Paul,Football
Paul,Reading
Riya,Singing
Riya,Dancing
Jack,Gaming
I don't want above output I want wherever there is same name is coming in a same object don't console it like below:
Paul,Football
"",Reading
Riya,Singing
"",Dancing
Jack,Gaming
Below is my code:
const data = [
{
name:'Paul',
hobbies: ['Football','Reading']
},
{
name:'Riya',
hobbies: ['Singing','Dancing']
},
{
name:'Jack',
hobbies: ['Gaming']
}
]
const example = (data) => {
for(var i=0;i<data.length;i++){
for(var j=0;j<data[i].hobbies.length;j++){
console.log(data[i].name,data[i].hobbies[j]);
if(i=0){
console.log(data[i].name,data[i].reports[j]);
}
else{
const prev = i-1;
if(data[prev].name == data[i].name) { //Getting TypeError here cannot read property 'name' of undefined
console.log("",data[i].reports[j]);
}
else{
console.log(data[i].name,data[i].reports[j]);
}
}
}
}
}
example(data);
In above code I am trying to compare the previous value of name in data array with the current value of name. If it's same then making name field " " else putting name value and for first element for position 0 I am putting value as it is.
Why am I getting this TypeError?

There are several issues, first is typo, you assigned instead of comparing
if (i=0) {
// ^^^^^
console.log(data[i].name,data[i].reports[j]);
}
The rest is logic, all you have to do is to check the index of j
const example = data => {
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].hobbies.length; j++) {
if (j == 0) {
console.log(data[i].name, data[i].hobbies[j])
} else {
console.log("", data[i].hobbies[j])
}
}
}
}
Full solution
const data = [
{
name: "Paul",
hobbies: ["Football", "Reading"],
},
{
name: "Riya",
hobbies: ["Singing", "Dancing"],
},
{
name: "Jack",
hobbies: ["Gaming"],
},
]
const example = data => {
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].hobbies.length; j++) {
if (j == 0) {
console.log(data[i].name, data[i].hobbies[j])
} else {
console.log("", data[i].hobbies[j])
}
}
}
}
example(data)

const data = [
{
name:'Paul',
hobbies: ['Football','Reading']
},
{
name:'Riya',
hobbies: ['Singing','Dancing']
},
{
name:'Jack',
hobbies: ['Gaming']
}
]
data.forEach(d => {
d.hobbies.forEach((hobby, index) => {
const name = index == 0 ? d.name : '""'
console.log(name + ',' + hobby)
})
})
Just print the name if index of hobby is 0

Related

How do you combine two like arrays of objects into a single array object?

I'm sorry if I'm asking a question that has been asked before, I had a hard time wording this one.
Basically, my API is returning an array of objects that are alike
const response.survey = [
{
1: { id: 1, user: user_1, points: 5 },
2: { id: 2, user: user_2, points: 3 }...
}
],
[
{
1: { id: 1, user: user_1, points: 10 },
2: { id: 2, user: user_2, points: 0 }...
}
],...
This can carry on for hundreds of arrays potentially, depending on users submissions through our forms. I'm stuck on how to combine them into something like:
[
{ user: user_1, points: 15 },
{ user: user_2, points: 3 },...
]
Note that the data that returned from the api has a key for the object, like Array[Object[1]], Array[Object[2]], etc.
In my current development environment, I'm returning 2x sets of 25 data points, so I would expect my final array of objects to be indexed at 25, but right now I'm getting 52. I believe there is a shorter way to handle this, but I cant quite figure it out and I keep going in circles.
Here is what I've tried:
let newArr = [];
response.survey.map((ballot, i) => {
for (const key in ballot) {
if (newArr.length == 0) {
let newObj = {
name: pos[key].user,
points: pos[key].points
}
newArr.push(newObj);
} else {
for (let k = 0; k < newArr.length; k++) {
if (newArr[k].name === pos[key].name) {
newArr[k].points += pos[key].points;
} else {
if (k + 1 == newArr.length) {
let newObj = {
name: pos[key].name,
points: pos[key].points
}
newArr.push(newObj);
}
}
}
}
}
}
I think I've been working on this issue for so long that I've started to go into circles and heading down the wrong path.
Any help would be greatly appreciated.
This solved my problem
await fetch('/api/getBallots')
.then((response) => response.json())
.then(async (data) => {
let newArray = []
data.ballots.map((ballot, i) => {
for (const key in ballot) {
if(!ballot[key].name) {
return;
} else {
let newObj = {
name: ballot[key].name,
points: ballot[key].points
}
newArray.push(newObj);
}
}
});
let rankings = [];
for (let i = 0; i < newArray.length; i++) {
if (rankings.length == 0) {
rankings.push({
name: newArray[i].name,
points: newArray[i].points
});
} else {
const index = rankings.findIndex((item) => item.name == newArray[i].name);
if (index == -1) {
rankings.push({
name: newArray[i].name,
points: newArray[i].points
})
} else {
rankings[index].points += newArray[i].points;
}
}
}
})

Problem when comparing JavaScript objects in an array

I have these 2 arrays of information. I want to resolve this problem: (Given the name of an user and a required permission, return true if
the user have that permission and false otherwise.)
const groups = [
{
id: 1,
name: 'admins',
permissions: ['CREATE', 'DELETE', 'READ', 'WRITE'],
},
{
id: 2,
name: 'readers',
permissions: ['READ'],
},
{
id: 3,
name: 'writers',
permissions: ['WRITE'],
},
{
id: 4,
name: 'managers',
permissions: ['CREATE', 'DELETE'],
}
];
const users = [
{
name: 'john',
groups: [1],
},
{
name: 'mary',
groups: [2, 3],
},
{
name: 'alice',
groups: [2]
},
{
name: 'bob',
groups: [3],
},
{
name: 'eve',
groups: [2, 4],
},
];
the code I've written so far:
function userHasPermission(userName, requiredPermission) {
//looping through first array
for (i = 0; i < users.length; i++) {
if (users[i].name === userName) {
// looping through the second array
for (j = 0; j < groups.length; j++) {
//here I don't know how to resolve this comparison, because as far as I understand it, the script has to check if userName is a valid ID inside groups array?
if (users[i].groups.includes(groups[j].id) && (groups[j].permissions.includes(requiredPermission))) {
return true;
} else {
return false;
}
}
}
}
};
userHasPermission("mary", "WRITE");
I'm new to Vanilla JavaScript and I'm stuck at this point, any help will be appreciated!
function userHasPermission(userName, requiredPermission) {
//looping through first array
for (i = 0; i < users.length; i++) {
if (users[i].name === userName) {
// looping through the second array
for (j = 0; j < groups.length; j++) {
if (users[i].groups.includes(groups[j].id) && (groups[j].permissions.includes(requiredPermission))) {
return true;
} else {
continue; // don’t return false yet.
}
}
}
}
// only when you’ve checked all possibilities
// still find no match, now you can return definitely
return false;
};
Above is imperative for-loop style based on your code. I personally prefer more functional code style. For your reference:
function userHasPermission(userName, requiredPermission) {
const targetUser = users.find(user => user.name === userName);
if (!targetUser) return false;
const userGroups = groups.filter(g => targetUser.groups.includes(g.id));
const permissions = userGroups.flatMap(g => g.permissions);
return permissions.includes(requiredPermission);
}
function userHasPermission(userName, requiredPermission) {
const user = users.find(u => u.name === userName);
let result = false;
user.groups.forEach(id => {
const group = groups.find(g => g.id === id);
result = group.permissions.includes(requiredPermission);
});
return result;
};
userHasPermission("mary", "WRITE");

JavaScript: How to convert nested array of object to key-value pair objects

It can be duplicate question but i have tried a lot but i did not get expected result.Could some one help me.
I am getting an array in request body like :
[
{
"name":"array",
"book":[
{
"name":"name1",
"book":"book1"
},
{
"name":"name2",
"book":"book2"
}
]
},
{
"name":"name3",
"book":"book3"
}
]
And I need to convert the array of nested array to below format
{
array: [
{
name1: "book1"
},
{
name2: "book2"
}
],
name3: "book3"
}
Note:In some cases book can be array or string.
On my first attempt i have tried below code to convert it into single object but it doest not convert nested array to key value pair
const array=[
{
"name":"array",
"book":[
{
"name":"name1",
"book":"book1"
},
{
"name":"name2",
"book":"book2"
}
]
},
{
"name":"name3",
"book":"book3"
}
]
var result = {};
for (var i = 0; i < array.length; i++) {
result[array[i].name] = array[i].value;
}
console.log(result);
Response for the above code
{
array: [
{
name: "name1",
book: "book1"
},
{
name: "name2",
book: "book2"
}
],
name3: "book3"
}
EDITED
I have made little change in the Code from the Ahmed's answer and it worked
const res=[
{
"name":"array",
"book":[
{
"name":"name1",
"book":"book1"
},
{
"name":"name2",
"book":"book2"
}
]
},
{
"name":"name3",
"book":"book3"
}
]
const obj = {}
for(let i = 0 ; i < res.length; i++){
let name = res[i].name
if(Array.isArray(res[i]['book'])){
obj[name] = [];
for(let item in res[i]['book']){
let key = res[i]['book'][item]['name']
let value = res[i]['book'][item]['book']
let entry = {}
entry[key] = value
obj[name].push(entry)
}
}
else{
obj[res[i].name]=res[i].book;
}
}
console.log(obj);
The added snippet should solve your problem.
The problem in your code was Appropriate nesting you didn't access the wanted values and didn't handle all the cases Hence, The wrong output.
const res = [
{
"name":"array",
"book":[
{
"name":"name1",
"book":"book1"
},
{
"name":"name2",
"book":"book2"
}
]
},
{
"name":"name3",
"book":"book3"
}
]
const obj = {}
for(let i = 0 ; i < res.length; i++){
let name = res[i].name
if(Array.isArray(res[i]['book'])){
obj[name] = []
for(let item in res[i]['book']){
let key = res[i]['book'][item]['name']
let value = res[i]['book'][item]['book']
let entry = {}
entry[key] = value
obj[name].push(entry)
}
}
else{
obj[name] = res[i]['book']
}
}
for(let item in obj){
console.log(item)
console.log(obj[item])
}

Get Unique Key-Value count as an object

I've got the following response from the server:
I want to get the unique key with the occurrence count.
In the following format:
0:{"name":"physics 1","count":2}
1:{"name":"chem 1","count":6}
I've already checked How to count the number of occurrences of each item in an array? but that is not I want.
Here is an es6 solution.
const data = [{
id: 0,
name: 'physics 1',
questionId: 1,
questionNr: 1
}, {
name: 'physics 1',
}, {
name: 'chem 1',
}, {
name: 'chem 1',
}, {
name: 'chem 2',
}];
const grouped = data.reduce((groups, cur) => {
const key = cur.name;
groups[key] = (groups[key] || 0) + 1;
return groups;
}, {});
const result = Object.keys(grouped).map(key => ({name: key, count: grouped[key]}));
console.log(result);
You could do it this way:
var source = [
{'section_name': 'test1'},
{'section_name': 'test2'},
{'section_name': 'test1'},
];
var temp = {};
for (var i = source.length - 1; i >= 0; i--) {
var key = source[i].section_name;
if (!temp[key]) {
temp[key] = 0;
}
temp[key] += 1;
}
var keys = Object.keys(temp);
var result = [];
for (var i = keys.length - 1; i >= 0; i--) {
var key = keys[i];
result.push({"name":key,"count":temp[key]});
}
console.log(result);
use this function this uses map and filter
t.reduce((f,l)=>{
var k=f.filter(elem=>elem.section_name==l.section_name);
if(k.length==1) k[0].count++;
else f.push({section_name:l.section_name,count:1})
return f;
},[] )
you can check this against this to verify
var t=[{section_name:"Physics"},{section_name:"Physics"},{section_name:"Chemistry"},{section_name:"Chemistry"},{section_name:"Physics"}]

JavaScript. Extract values from associative array

How can I get the values from this associative array in JavaScript?
I just need the email addresses and not the labels.
(
{
office = ("my#email.com");
home = ("ahome#anotheremail.com");
work = ("nothing#email.com");
},
{
home = ("test#test.se");
}
)
UPDATE: Prefered output in JSON would be:
{
"data": [
{
"email": "my#email.com"
},
{
"email": "ahome#anotheremail.com"
},
{
"email": "nothing#email.com"
},
{
"email": "test#test.se"
}
]
}
Thankful for all input!
What you probably meant to do is:
var x = [{
office: ("my#email.com"),
home: ("ahome#anotheremail.com"),
work: ("nothing#email.com")
},
{
home: ("test#test.se")
}]
and:
for(var j = 0; j < x.length; j++)
{
for(var anItem in x[j])
{
console.log(x[j][anItem])
}
}
// EDIT:
however, it's not the best practice to use for … in.
Maybe you could change your data structure to:
var x = [[{
value: "my#email.com",
type: "office"
},
{
value: "ahome#anotheremail.com",
type: "home"
},
{
value: "nothing#email.com",
type: "work"
}],
[{
value: "test#test.se",
type: "home"
}]];
and iterate over using:
for( var i = 0, xlength = x.length; i < xlength; i++ )
{
for( var j=0, ylength = x[i].length; j < ylength; j++ )
{
console.log(x[i][j].value);
}
}
Here's a one-liner:
console.log(Object.keys(assoc).map(k => assoc[k]));
where assoc is your associative array.
Edit
I have a better answer here.
You can 'foreach' over the object to get it's properties:
for(var j = 0; j < mySet.length; j++)
{
for(var propName in mySet[j])
{
var emailAddress = mySet[j][propName];
// Do Stuff
}
}
Answer for edited question:
var ret = {data: []};
for(var j = 0; j < x.length; j++)
{
for(var anItem in x[j])
{
ret.data.push({
email: x[j][anItem]
});
}
}
console.log(ret);
The result is kept in ret.
Is it your input in JSON format? Because if so, it's the wrong syntax. However
let _in = [
{
office : "my#email.com",
home : "ahome#anotheremail.com",
work : "nothing#email.com",
},
{
home : "test#test.se"
}
]
let _out = []
_in.forEach( record => {
_out = _out.concat(Object.values(record).map(x => new Object({email : x})))
})
console.log(_out)
for each record I extracted values and "packed" into an object with the "email" attrbiute, then I merged all those arrays obtained from the original array of records
It seems that you're looking for Object.values.

Categories

Resources