Related
I have some JSON that looks like this
var js = '{
"person" : {
"firstname" : "Steve",
"lastname" : "Smith",
"other": [
{
"age" : "32",
"deceased" : false
},
{
"age" : "14",
"deceased" : false
},
{
"age" : "421",
"deceased" : false
}
]
}
}'
I know how I delete all of "other" by doing this
var j = JSON.parse(js)
delete j[person.other]
but what I really want is to delete the "other" node with a condition that is age = 14.
The result JSON I am looking for is
{
"person" : {
"firstname" : "Steve",
"lastname" : "Smith",
"other": [
{
"age" : "32",
"deceased" : false
},
{
"age" : "421",
"deceased" : false
}
]
}
}
I have looked at the delete operator here and it does not provide a conditional.
Sorry if this is too simple a question. I am learning.
Thanks
The best approach to this would be not to alter the json, but create another one instead:
const filtered = { ...json, other: json.other.filter(item => item.age !== "14") }
If you really need to alter the json, you can do the following:
let index = json.other.findIndex(item => item.age === "14")
while (index !== -1) {
json.other.splice(index, 1)
index = json.other.findIndex(item => item.age === "14")
}
You can use a filter on the array doing something like
j[person.other].filter(x => x.age != 14)
Doc on how filter works more in depth here :
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to count occurance of every element in this JSON file.
[
{
"firstName": "Sena",
"lastName": "Turan",
"age": 19,
"retired": false
},
{
"firstName": "Çınar",
"lastName": "Turan",
"age": 1,
"retired": false
},
{
"firstName": "Ahmet",
"lastName": "Turan",
"age": 55,
"retired": true
}
]
Like how many "firstName" or "age" variables it contains. Anyone has an opinion on this? Thanks.
You can reduce your array and up the count for every element in the objects of the array:
const arr = [{ "firstName" : "Sena", "lastName" : "Turan", "age" : 19, "retired" : false}, {"firstName" : "Çınar", "lastName" : "Turan", "age" : 1, "retired" : false}, {"firstName" : "Ahmet", "lastName" : "Turan", "age" : 55, "retired" : true} ];
const result = arr.reduce((acc, curr) => {
for(let el in curr) {
acc[el] = acc[el] == null ? 1 : acc[el] + 1;
}
return acc;
}, {});
console.log(result);
You could also simply go through all of the items and check for the specific item you want:
const arr = [{ "firstName" : "Sena", "lastName" : "Turan", "age" : 19, "retired" : false}, {"firstName" : "Çınar", "lastName" : "Turan", "age" : 1, "retired" : false}, {"firstName" : "Ahmet", "lastName" : "Turan", "age" : 55, "retired" : true} ];
const count= (it) => {
let count = 0;
for (el of arr) {
if(el[it]) {
count++;
}
}
return count;
};
console.log(count("firstName"));
If I may add my attempt, this is written in ES6:
const countAppearance = key => {
let count = 0;
arr.forEach(record => (count += record[key] ? 1 : 0));
return count;
};
#tunayvaz Also, one very CRUCIAL detail: all these functions don't actually check for the key itself, they check for the existence of the value of that key. Meaning, if you make all "age" undefined, it will give you 0, even though age appears in all 3 records. If you want a strictly working function, you might want to have a look at Object.keys() or something.
yourArray.filter(person => 'age' in person).length should work for the age, for an example. YOu can tweak it for other properties.
This is by far the most common question asked in SO, however, all in all, the questions asked refers to merging two whole objects.
In my case, it's quite different.
Suppose I'm given:
const P1 = {
"name" : "Person1",
"profession" : "Student",
"gender" : "Male",
"type" : "Patient",
}
const E1 = {
"age" : "30",
"dob" : "20/12/1970",
"address" : "122 Harrow Street",
"contactNumber" : "07473033312",
}
and I want to merge these two to give me the following:
const Result = {
"name" : "Person1",
"type" : "Patient",
"age" : "30",
"dob" : "20/12/1970",
}
The issue is, I don't want to merge two whole projects. I want to merge specific props without looping.
Currently, we can achieve the merge by using the spread like so:
const data = [...P1, ...E1];.
But this merges both, which I don't want.
const result = (({name, type}, {age, dob}) => ({name, type, age, dob}))(P1, P2);
Just partially destruct P1 and P2 and build up a new object.
Since you're looking for an ES6 way, I'd say using deconstruction is the way to go:
const P1 = {
"name" : "Person1",
"profession" : "Student",
"gender" : "Male",
"type" : "Patient",
}
const E1 = {
"age" : "30",
"dob" : "20/12/1970",
"address" : "122 Harrow Street",
"contactNumber" : "07473033312",
}
const { name, type } = P1;
const { age, dob } = E2;
const Result = { name, type, age, dob };
You could use a complete dynamic approach by using an array for the wanted properties and another for the objects.
Then build a new object out of the found objects.
var p1 = { name: "Person1", profession:"Student", gender:"Male", type:"Patient" },
e1 = { age: "30", dob:"20/12/1970", address:"122 Harrow Street", contactNumber:"07473033312" },
keys = ['name', 'profession', 'age', 'dob'],
objects = [p1, e1],
merged = Object.assign(...keys.map(k => ({ [k]: objects.find(o => k in o)[k] })));
console.log(merged);
I guess your best bet is to unpack and then pack it again:
let {name, type, age, dob} = {...P1, ...E1};
result = {name, type, age, dob}
This is silly, but that's all we've got in ES6.
An alternative would be a function like lodash's _.pick.
If you have an array of source objects, replace {...P1, ...E1} with spreaded Object.assign:
let {name, type, age, dob} = Object.assign({}, ...a);
If you're aware of what properties the merged object should have (in your case name, type, age, dob)
How about defining them like so:
const P1 = {
"name" : "Person1",
"profession" : "Student",
"gender" : "Male",
"type" : "Patient",
}
const E1 = {
"age" : "30",
"dob" : "20/12/1970",
"address" : "122 Harrow Street",
"contactNumber" : "07473033312",
}
const Result = {
"name" : P1.name || E1.name,
"type" : P1.type || E1.type,
"age" : P1.age || E1.age,
"dob" : P1.dob || E1.dob,
}
I have a JSON object that I need to create a list out of.
I would be able to do it fine but each object can have children. It looks something like this :
{
"Boys" :
[
{
"name" : "Fred",
"age" : "65",
"children" : [{
"name" : "dave",
"age" : "24",
"children" : []
}, {
"name" : "cliff",
"age" : "32",
"children" : []
}
]
},
{
"name" : "jon",
"age" : "46",
"children" : [{
"name" : "jess",
"age" : "26",
"children" : []
}, {
"name" : "gloria",
"age" : "19",
"children" : []
}
]
}
],
"Girls" :
[
{
"name" : "Jane",
"age" : "65",
"children" : [{
"name" : "dave",
"age" : "24",
"children" : []
}, {
"name" : "grace",
"age" : "32",
"children" : []
}
]
},
{
"name" : "ariana",
"age" : "46",
"children" : [{
"name" : "jessy",
"age" : "28",
"children" : []
}, {
"name" : "niki",
"age" : "19",
"children" : []
}
]
}
]
}
I'd be able to go through it fine in a for-loop but I'm unsure how to go through the children too.
Basically I want to go through each element and create a list item with the text being the name of the object I am currently at.
So for the JSON above it would be something like :
-Boys
-Fred
-Dave
-Cliff
-Jon
-Jess
-Gloria
-Girls
-Jane
-Dave
-Grace
-Ariana
-Jessy
-Niki
After I create this list I will be using JSTree to format it, any help is appreciated :)
You need a recursive function, a function that calls itself until something happens. In your case, you need a function that goes through a list of people. For each person, it'd paint the name, then would check if that person has children. If it does, then calls the function again, passing it the list of children.
Something like this:
var renderList = function(list){
var $list = $('<ul>');
$.each(list, function(i, element){
var $child = $('<li>'+element.name+'</li>');
if (element.children.length > 0) {
$child.append(renderList(element.children));
}
$list.append($child);
});
return $list;
};
$('#boys').append(renderList(data.Boys)); // Start list of boys
$('#girls').append(renderList(data.Girls)); // Start list of girls
Working example here http://jsfiddle.net/zbm778ag/
In the following JSON object:
var employees = { "accounting" : [ // accounting is an array in employees.
{ "firstName" : "John", // First element
"lastName" : "Doe",
"age" : 23 },
{ "firstName" : "Mary", // Second Element
"lastName" : "Smith",
"age" : 32 }
], // End "accounting" array.
"sales" : [ // Sales is another array in employees.
{ "firstName" : "Sally", // First Element
"lastName" : "Green",
"age" : 27 },
{ "firstName" : "Jim", // Second Element
"lastName" : "Galley",
"age" : 41 }
] // End "sales" Array.
} // End Employees
How do I restructure the object so I can access each employee first name like this:
employees[0].firstName
employees[1].firstName
// etc
It would require restructuring it so that you'd eliminate the "accounting/sales" properties and make employees an Array of Objects.
Example: http://jsfiddle.net/hgMXw/
var employees = [
{
"dept": "accounting", // new property for this object
"firstName": "John",
// First element
"lastName": "Doe",
"age": 23
},
{
"dept": "accounting", // new property for this object
"firstName": "Mary",
// Second Element
"lastName": "Smith",
"age": 32
},
{
"dept": "sales", // new property for this object
"firstName": "Sally",
// Third Element
"lastName": "Green",
"age": 27
},
{
"dept": "sales", // new property for this object
"firstName": "Jim",
// Fourth Element
"lastName": "Galley",
"age": 41
}
]
You can't pivot this like that. Either you move the department as a key in the employee object or you have to access it like employees.accounting[0].firstName.
If you insist on accessing the employee as employees[index], you have to restructure it to:
var employees = [
{ "firstName" : "John", "lastName" : "Doe", "age" : 23, "department" : "accounting" },
{ "firstName" : "...", ..., "department" : "accounting" },
... and so on.
];
and introduce a different way to filter by department.
maybe create a function that loop through the employees array, and copy each element that match the filter into a new array object and return it.
function getAllEmployeesFilteredBy(filterName, filterValue, empArray)
{
var result = [];
for (var i=0; i < empArray.length; i++) {
if (empArray[i][filterName] === filterValue)
//by ref
result[result.length] = empArray[i];
//or if you prefer by value (different object altogether)
//result[result.length] = { "firstName" : empArray[i].firstName, "lastName" : empArray[i].lastName, ... }
}
return result;
}
From jsFiddle
var employees = { "firstName" : "John", // First element
"lastName" : "Doe",
"age" : 23 },
{ "firstName" : "Mary", // Second Element
"lastName" : "Smith",
"age" : 32 }
;
alert(employees);