Delete child object from parent object in Javascript - javascript

seemed like a simple task but im finding it hard to achive.
I have object containing child objects, and while looping over them i would like to delete an inner object in based on value of one of it's fields (this field exists in every inner object).
the loop goes like this:
for (let old_item of this.updated_items) {
if (old_item['content_id'] === item.content_id) {
this.updated_items.***DELETE***(old_item)
}
}
I marked location where is the missing logic.
How would i delete old_item from this.updated_items?
ES6 if possible..thx

You can iterate the Object#entries, and when the correct content_id is found on the value, delete the key from the original object.
for (const [key, value] of Object.entries(this.updated_items)) {
if (value.content_id === item.content_id) {
delete this.updated_items[key];
}
}
Since Object#entries is not supported by some browsers, another option is to use Array#forEach to iterate the object's keys, and if the content_id is found delete the key from the original object:
Object.keys(this.updated_items) // get the object's keys
.forEach((key) => // iterate the keys
this.updated_items[key].content_id === item.content_id // if the content id is similar
&&
delete this.updated_items[key] //delete the key from the original object
)

You can use the filter function over an array, and convert your object to an array using Array.from:
this.update_items = Array.from(this.updated_items).fiter(old_item => old_item.content_id !== item.content_id)

Related

Filter Array of Inner Arrays Based on Inner Array Length

I need to filter out the empty arrays inside the array called arr.
Here's what I see when I console.log([arr]):
I have tried console.log([arr].filter(arr => arr.length > 0)) with no luck (getting [])
As was pointed out by #robin-zigmond, you are dealing with an object here containing array properties.
You can use the delete operator to delete properties from an object:
for (let prop in arr) {
if (arr[prop].length === 0) {
delete arr[prop];
}
}
This will remove all zero-length properties from the arr object.

JS reduceRight is causing arrays to become objects, how can I fix the logic?

I have an json object:
json = {
"array": [80, 50]
}
A third party jsoneditor, returns a path variable as a list of strings or index to the value. I use event listeners to detect changes to the value and I store those changes in a separate object to later submit to a form.
For example, if I change 50 to 60, this is what is returned:
node.path = ["array", 1]
node.value = 60
I am using reduceRight() to normally map the changes to the object to the changed object, however when the value is an Array it is converting the array to an object.
let delta = node.path.reduceRight((obj, elem) => ({[elem]: obj}), node.value)
//returns
delta = {array: {1: 60}}
//instead of
delta = {array: [80, 60]}
How can I check the original json and if the field is an Array object, don't reduce this into an object but keep the original Array and update the Array with the changed value within the Array? I need to submit the entire array into the form.
EDIT:
I know that I can do some custom logic within the reduce to check the original json and get the unchanged part of the array. I just dont know how to achieve that
let delta = node.path.reduceRight( function (obj, elem) {
//some logic here to account for arrays and get original array list and change only slected index
else {
return {[elem]: obj}), node.value
}
});
EDIT:
Alternatively, how can can I get the nested keys from the node.path and find the original array and then just update the array index? The path can sometimes be nested sothe path is always going to be the Array-like structure.
//this does not work
let orig_key_val = json[node.path]
Thanks!
This seems to work, finally... I used a regular reduce() and check if the key is an Array if it is store my original Array into a tmp object and save that key. The next time the reduce() comes around, if the index is on the last path element then set the tmp[tmp_key][key] to my target value and return the adjusted for Array object instead.
I can see how this will not work for nested json objects but for now I dont have any... Unless someone can show me how to figure that one out this is my implementation for now.
let tmp = {};
let tmp_key;
let delta = node.path.reduce((val, key, index, array) => {
if (Array.isArray(json[key])) {
tmp[key] = json[key]
tmp_key = key;
} else if (Object.keys(tmp).length !== 0 && index === node.path.length-1) {
tmp[tmp_key][key] = node.value;
return tmp
} else
return {[key]: val}
}, node.value);

best way to change value of an object from an array of objects when given a key

I'm working (learning) in React. I have an array of objects which hold info on gamertags. They are rated with up to five stars and this function is called when a user clicks on the stars in the GUI to alter the rating.
my solution:
I make a copy of state, iterate over the copy, check each entry for the key, reassign the number of stars, then use my setState hook to assign the altered array.
Is there a more concise way to do this? I searched all over stack and google and couldn't find anything. I feel like I should be able to map, use an arrow function and or a ternary. Thanks for any comments on styles, JS and ES6 seems to be all about that. Thx fam.
function changeStars(stars, key) {
console.log(stars, key);
const newRatingInventory = [ ...tagInventory];
for (const [index] of newRatingInventory.entries()) {
if (newRatingInventory[index].timeStamp === key) {
newRatingInventory[index].stars = stars;
}
}
setTagInventory([...newRatingInventory]);
Using the spread syntax doesn't creates a deep copy - it just creates a new array but the objects are not cloned. So any changes made to any object inside the new array will mutate the original object.
Currently you are mutating the state directly which is not the correct way to update the state in React.
You should use the .map() method to iterate over the array, create and return a new object if the condition newRatingInventory[index].timeStamp === key evaluates to true.
function changeStars(stars, key) {
const newState = tagInventory.map(obj => {
if (obj.timeStamp === key) {
// return a new object with the updated
// value of "stars" property.
return { ...obj, stars };
}
// if the above condition is not true,
// return the current object as it is.
return obj;
});
// update the state
setTagInventory(newState);
}
There is a multipal way to do this
my recommendation one is map.
const changeStars = (stars, key) => {
let tempRating = tagInventory && tagInventory.length > 0 &&
tagInventory.map(item => item.timeStamp === key ? {...item, stars} : item);
setTagInventory(tempRating)
}

Read a value from JSON Array without entity

I need to access the 2.2.10.60 and "bank overdrafts...." value from the following array --
May I ask about how to get it?
Here with my code.
var json=chunk.toString();
var obj = JSON.parse(json);
session.send(obj.clauses[0]);
console.log(obj.clauses[0]);
But I can't get the value of "2.3.10.60" and "Bank overdrafts....".
and the inside the "clauses" array will always change.
I had Solved by my own:
var graph = JSON.parse(json);
for(var i=0;i<graph.clauses.length;i++){
var obj=graph.clauses[i];
console.log(obj);
var clause_id;
var clause_text;
for(var key in obj)
{
clause_id=key;
clause_text=obj[key].toString();
session.send(clause_id+"<br>"+clause_text);
}
}
You could use Array#find and check if the wanted property exist in the object. Then take the object and use an property accessor for the result.
key = '2.2.10.60'
result = clauses.find(object => key in object)[key];
If you are not sure about if the array does not contain any object with this key, take an default object or check in advance if find returns a truthy value (like an object), take this
var key = '2.2.10.60'
result,
temp = clauses.find(object => key in object);
if (temp) {
result = temp[key];
}
For a dynamic approach, you could take a variable for the wanted key.
For getting just the first entry of the object, you could take the entries of index zero. This approach assumes, theat only one key/value pair exists in the object.
var [key, value] = Object.entries(object.clauses[0])[0];
// ^^^^^^^^^^^^ target by destructuring an array
// ^^^^^^ source
// ^^^^^^^ property
// ^^^ index/the first one
// ^^^^^^^^^^^^^^ ^ get all key/value pairs of object
// ^^^ take the first pair only
You can use the Array.find() method and verify if the object keys have the value you need.
clauses.find(object => Object.keys(object).includes('2.2.10.60'))
This will return an array of the first object whose keys include '2.2.10.60'

Javascript - Inserting unique elements in Array: Multidimensional check x Temporary unidimensional array

I don't know if it's a stupid question, but here it comes:
Imagine an array of unordered objects like:
[{id:4, name:"a"},{id:2, name:"b"},{id:3, name:"ee"},{id:1, name:"fe"},.....].
This array is dinamically created inside a loop using javascript, but, everytime I'll push something to the array I must check if an object with the same id exists and only pushs the newones.
Which one is faster:
1) At every loop check manualy the entire array.
or
2) Create a temporary unidimensional array only with ids and use indexOf to check if the new object id is present and then, if not present at the temporary array, add it to the original array.
How about
var a = []
var o = { id:10, name:"xyz" }
if(typeof a[o.id]=="undefined") {
a[o.id] = { name:o.name }
}
? That should be fastest for most machines. Or to not change your object structure
a[o.id] = { id:o.id, name:o.name }
But the better approach would be
function getA(i) { if (typeof a[i] == "undefined") return null;
return { id:i, name:a[i].name }; }

Categories