delete from json conditionally - javascript

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

Related

How to count certain elements in an object array in JavaScript? [closed]

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.

Json Array object to string logic

Not sure if I'm repeating the question or concept.
How do I convert the below sample to the below string format (may not be correct JSON format)
[{ "Name":"Test1","check":"true},{ "Name":"Test2","check":"true},{ "Name":"Test3","check":"false"}]
string format with appending - for false
Expected o/p:
"Test1","Test2","-Test3"
I have tried concatenating, but it always ends up with
"Test1,Test2-Test3"
But I am looking for 3 separate string separated by comma. Any hint would help
You can simply iterate through your array and collect the object in your required format:
var obj = [{
"Name" : "Test1",
"check" : true
}, {
"Name" : "Test2",
"check" : true
}, {
"Name" : "Test3",
"check" : false
}
];
var result = obj.map(function(x) {
return x.check ? x.Name : "-" + x.Name;
});
document.body.innerHTML = JSON.stringify(result);
Note that I have changed the format of your JSON in order to make it valid.
Just in case if you actually have a string true and false, and you can't change this, you can simply compare it as a string:
var obj = [{
"Name" : "Test1",
"check" : "true"
}, {
"Name" : "Test2",
"check" : "true"
}, {
"Name" : "Test3",
"check" : "false"
}
];
var result = obj.map(function(x) {
return x.check === 'true' ? x.Name : "-" + x.Name;
});
document.body.innerHTML = JSON.stringify(result);
HTML
<div id="output"></div>
Javascript
var obj = [{
"Name" : "Test1",
"check" : true
}, {
"Name" : "Test2",
"check" : true
}, {
"Name" : "Test3",
"check" : false
}
];
function getNames(){
var length=obj.length;
// alert(length);
var op=[];
for(var i=0;i<obj.length;i++){
// alert(obj[i].Name);
op[i]='"'+obj[i].Name+'"';
}
document.getElementById("output").innerHTML=op;
}
getNames();
Your output is there as expected.
Just loop through the valid JSON array(obj) and append the required values(obj.Name) to the empty string(str) based on the condition(appending '-' for 'false' value of obj.check).
var obj = [{
"Name" : "Test1",
"check" : true
}, {
"Name" : "Test2",
"check" : true
}, {
"Name" : "Test3",
"check" : false
}
];
var str = '';
for(var x in obj){
str += (obj[x].check === true) ? obj[x].Name : '-'+obj[x].Name;
str += (x != (obj.length-1)) ? ',' : '';
}
alert(str);

Javascript Object output to Array

This is a very very simple question, but for some reason I'm stuck with it.
How can I take an object like:
var billionaire = {
"10" : {
"firstName" : "Steve",
"lastName" : "Jobs",
"company" : "Apple"
},
"11" : {
"firstName" : "Bill",
"lastName" : "Gates",
"company" : "Microsoft"
},
"12" : {
"firstName" : "Warren",
"lastName" : "Buffet",
"company" : "Berkshire Hathaway"
}
};
And Output it into an array like this using pure javascript
var arr = [
"Steve",
"Bill",
"Warren"
];
I do just need the firstName in the array. Thanks for your help and sorry for the easy question.
You can do
var arr = Object.keys(billionaire).map(function(k){ return billionaire[k].firstName });

Displaying array value based on a certain array key as a user type in a text field

I have looked at Display partial array value matches from user input and tried to achieve the same results.
The difference is the array format. I want the search text value to match the array key, name.
No matter what I type in the text field, it displays "no match found!" and I can never display the names. It seems players[x].name.indexOf() is not recognized. How can I display names?
Here is Fiddle
var players = [
{ "id" : "23012",
"name" : "Scott",
"first" : "Stve",
"last" : "Scott" },
{ "id" : "22904",
"name" : "Phillips, A",
"first" : "Adam",
"last" : "Phillips"},
{ "id" : "45783",
"name" : "Phillips, T",
"first" : "Tom",
"last" : "Phillips" },
{ "id" : "54762",
"name" : "Scobery",
"first" : "Don",
"last" : "Scobery" },
{ "id" : "78903",
"name" : "Phillip",
"first" : "Roger",
"last" : "Phillip"}
]
$("#searchField").on("keyup", function() {
$(".append").empty();
if($("#searchField").val() != ""){
for(var x = 0; x < players.length; x++){
if(players[x].name.indexOf(($("#searchField").val()).toLowerCase()) == 0){
$(".append").append(players[x].name+"<br>");
} else {
$(".append").html("no match found!");
}
}
}
});
Update Fiddle
You are overriding all search results at first negative search.
Because you append append results, at first not found you kill all the appended children with .html() instruction.
It was just that mistake.
I'm not sure about your toLowerCase use, but this is another story.
var players = [{
"id": "23012",
"name": "Scott",
"first": "Stve",
"last": "Scott"
}, {
"id": "22904",
"name": "Phillips, A",
"first": "Adam",
"last": "Phillips"
}, {
"id": "45783",
"name": "Phillips, T",
"first": "Tom",
"last": "Phillips"
}, {
"id": "54762",
"name": "Scobery",
"first": "Don",
"last": "Scobery"
}, {
"id": "78903",
"name": "Phillip",
"first": "Roger",
"last": "Phillip"
}]
$("#searchField").on("keyup", function () {
var found = false;
$(".append").empty();
if ($("#searchField").val() != "") {
for (var x = 0; x < players.length; x++) {
if (players[x].name.indexOf($("#searchField").val()) >= 0) {
found = true;
$(".append").append(players[x].name + "<br>");
}
}
if (!found) {
$(".append").html("no match found");
}
}
}); // searchField on
To have the search completely case insensitive:
if (players[x].name.toLowerCase().indexOf($("#searchField").val().toLowerCase()) == 0)
Spam lowercase around. ( to the object and to the input )

JSON Object array inside array find and replace in javascript

I have one JSON Object like this :
var myObject = [
{
"Name" : "app1",
"id" : "1",
"groups" : [
{ "id" : "test1",
"name" : "test group 1",
"desc" : "this is a test group"
},
{ "id" : "test2",
"name" : "test group 2",
"desc" : "this is another test group"
}
]
},
{
"Name" : "app2",
"id" : "2",
"groups" : [
{ "id" : "test3",
"name" : "test group 4",
"desc" : "this is a test group"
},
{ "id" : "test4",
"name" : "test group 4",
"desc" : "this is another test group"
}
]
},
{
"Name" : "app3",
"id" : "3",
"groups" : [
{ "id" : "test5",
"name" : "test group 5",
"desc" : "this is a test group"
},
{ "id" : "test6",
"name" : "test group 6",
"desc" : "this is another test group"
}
]
}
];
I have new value available of "name" for specific "id".
How can I replace "name" of specific "id" inside any object ?
And how to count total number of groups among all objects ?
for example : replace name to "test grp45" for id = "test1"
Here is fiddle
http://jsfiddle.net/qLTB7/21/
The following function will search through an object and all of its child objects/arrays, and replace the key with the new value. It will apply globally, so it won't stop after the first replacement. Uncomment the commented line to make it that way.
function findAndReplace(object, value, replacevalue) {
for (var x in object) {
if (object.hasOwnProperty(x)) {
if (typeof object[x] == 'object') {
findAndReplace(object[x], value, replacevalue);
}
if (object[x] == value) {
object["name"] = replacevalue;
// break; // uncomment to stop after first replacement
}
}
}
}
Working jsfiddle: http://jsfiddle.net/qLTB7/28/
Try this
function findAndReplace(object,keyvalue, name) {
object.map(function (a) {
if (a.groups[0].id == keyvalue) {
a.groups[0].name = name
}
})
}
findAndReplace(myObject,"test1" ,"test grp45");
Here's a different approach using Array.prototype.some. It assumes that the Name property in the outer objects should be actually be name (note capitalisation).
function updateNameById(obj, id, value) {
Object.keys(obj).some(function(key) {
if (obj[key].id == id) {
obj[key].name = value;
return true; // Stops looping
}
// Recurse over lower objects
else if (obj[key].groups) {
return updateNameById(obj[key].groups, id, value);
}
})
}
The advantage of some is that it stops as soon as the callback returns true.
I think this should work for you:-
var id = 'test1';
var newname = 'test grp45';
var numberOfGruops = 0;
myObject.forEach(function(app){
numberOfGruops += app.groups.length; //Count all groups in this app
app.groups.forEach(function(group){
if(group.id===id)
group.name = newname; // replace the name
});
});
Maybe a more succinct sol'n
function changeName(objArray, objId, newName) {
objArray.forEach(function(obj) {
if (obj.id === objId) obj.Name = newName;
});
}
Personally: if this were me, when creating these objects, I would create a new obj and key them by id.
var myApps = {};
myObject.forEach(function(o) {
myApps[o.id] = o;
});
=>
{
"1": {
"Name": "app1",
"id": "1",
"groups": [
{
"id": "test1",
"name": "test group 1",
"desc": "this is a test group"
},
{
"id": "test2",
"name": "test group 2",
"desc": "this is another test group"
}
]
}
}
And then you could just do:
myApps['someId'].name = 'This is my new Name'
Check it out here:
http://jsfiddle.net/qLTB7/40/
it should be if (object["id"] == value) instead of if (object[x] == value) in 7th line of PitaJ answer, so whole function will look like:
function findAndReplace(object, value, replacevalue) {
for (var x in object) {
if (object.hasOwnProperty(x)) {
if (typeof object[x] == 'object') {
findAndReplace(object[x], value, replacevalue);
}
if (object["id"] == value) {
object["name"] = replacevalue;
// break; // uncomment to stop after first replacement
}
}
}
}
if you leave object[x] - function will replace name also for objects with other keys values set to "test1", for example
{"id": "xxx", "name": "test group 1", "desc": "test1"}

Categories

Resources