Removing an entire key from a JavaScript Object - javascript

This may be a case of my lack of terminology, however if someone could enlighten me on this I'd appreciate it:
I have a routine which returns a JSON array, works perfectly however I then wish to do some calculations based on what's passed.
I've therefore copied the array into a temporary object (called tmp), and I then wish to remove certain 'keys' (?) from this object that aren't necessary.
For example, my 'tmp' object starts out as having:
fldCat2, fldCat3 and many more.
What I don't need is anything related to 'fldCat3', so I wish to remove that entire key from the object.
To test this I've done the following:
console.log(tmp);
delete tmp.fldCat3;
delete tmp['fldCat3'];
var prop = "fldCat3";
delete tmp[prop];
console.log(tmp);
Yet not one of those delete methods deletes 'fldCat3' from the tmp object.
Is there something pretty damn obvious I'm missing?
edit
have attached a screenshot of the object from within Firebug (values removed)

Given your screenshot I am assuming that your problem is that you are trying to remove properties from what is actually an array of objects with these properties.
You will have to do something like this
for (var i = 0; i < tmp.length; i++)
delete tmp[i].fldCat3;
Here you loop through all the elements of said array removing fldCat3 from each of these.

I have experienced that problem too. What I have done is using UnderscoreJS's _.compact(myObject) after deleting the key from the object.

Related

Access Array with String key

I have two variables with JSON files. The first is a list of keys looks like this:
keylist = ["key1","key2","key3"]
The second one is generated from a database and looks like this:
data = {
"key1"{
#further data
},
"key2"{
#further data
},
"key3"{
#further data
}
}
Now I want to access the second element of the database with the key from the keylist
data.keylist[1];
Which doesn't work because the return of keylist[1] is a String? I did some research and the use of the window function was proposed. So I tried this:
window["data." + keylist[1]]();
Which leads to a "is not a function" error. What can I do to solve this problem?
As simple as that:
const mydata = data[ keylist[1] ];
Also, your code is correct from the point of syntax, but it tells completely different than you expect it to tell.
data.keylist[1];
tells JS that you expect to have an object called data which has a property called keylist and which is (most likely) type of array, and you want to get the second element of this array.
PS: And one more point here. Your question title is not completely correct because of the difference between Arrays and Object in JS.
There is no "string keys" for arrays in JS, so you cannot "access array with a string key". Well, truly speaking there are, but not for items of array. Array items only have numeric index, which you can use to access it. Objects, in contrast to arrays, may have named properties. So when you see something like that: data = myVar['data'], you can tell that you're dealing with an object, while data = someVar[0] can be both, an Array (most likely) or also an Object with key named '0'.
I don't think the issue you're having with your first example is because it returns a key. I believe the issue is because data doesn't have a property called keylist. Instead of that, try it as
data[keylist[1]]
and see if that works for you. The reason this one should work is that, in this situation, Javascript will evaluate the string return of keylist[1] and then use it as a string index for the data variable. Let me know if this works out for you :D
You can try using using something like this.
data[keylist[1]]

Console.log: the length of array is 0 and 1 at same time

About the console.log, i believe i have a case related to
Javascript array length of 0
In my console i got
my code related at 24
const lists = this.props.localData.lists;
if(lists.length === 0 ) {
console.log('lists',lists);
}
What is going on here?
if it is right in its way, how could i access lists[0](undefined)?
could anyone give me a hint?
Thanks in advance.
Some of the comments hinted at the issue here, but I don't see one that fully and correctly explains it. Here is what happened.
The initial one-line display of the array is created at the time you call console.log(). Simply viewing the log doesn't change anything (contrary to what one or two comments say). And subsequent updates to the array don't change this one-line view either.
But when you click the little triangle to expand the log entry, the expanded multiline display is created using the current array contents at the time you click the triangle. That is what causes the difference between the two. Your array was empty when you called console.log(), and you added an element to it after that but before you clicked to expand the display in the console.
If you want to get a full view of the array as it exists at the moment of the console.log() call, a good way to do it is to use JSON.stringify(). You can use the third argument to this function to pretty-print the result. So in your example, you might use:
console.log( JSON.stringify( lists, null, 4 ) );
Check this out: foo = [] create a new array and assigns a reference to it to a variable. Any other references are unaffected and still point to the original array.
foo.length = 0 modifies the array itself. If you access it via a different variable, then you still get the modified array.
Lucky with that.

What does this code using [].filter.call do?

I’m learning javascript and trying to write code that sorts a list, removing elements if they meet certain criteria.
I found this snippet that seems promising but don't have a clue how it works so I can adapt it to my needs:
list = document.getElementById("raffles-list").children; // Get a list of all open raffles on page
list = [].filter.call(list, function(j) {
if (j.getAttribute("style") === "") {
return true;
} else {
return false;
}
});
Can you guys help me learn by explaining what this code block does?
It's getting all the children of the "raffles-list" element, then returning a filtered list of those that contain an empty "style" attribute.
The first line is pretty self-evident - it just retrieves the children from the element with id "raffles-list".
The second line is a little more complicated; it's taking advantage of two things: that [], which is an empty array, is really just an object with various methods/properties on it, and that the logic on the right hand side of the equals sign needs to be evaluated before "list" gets the new value.
Uses a blank array in order to call the "filter" method
Tells the filter to use list as the array to filter, and uses function(j) to do the filtering, where j is the item in the list being tested
If the item has a style attribute that is empty, i.e. has no style applied, it returns true.
Edit:
As per OP comment, [].filter is a prototype, so essentially an object which has various properties just like everything else. In this case filter is a method - see here. Normally you just specify an anonymous function/method that does the testing, however the author here has used the .call in order to specify an arbitrary object to do the testing on. It appears this is already built into the standard filter method, so I don't know why they did it this way.
Array like objects are some of javascript objects which are similar to arrays but with differences for example they don't implement array prototypes. If you want to achieve benefits of array over them (for example like question filter children of an element )you can do it this way:
Array.prototype.functionName.call(arrayLikeObject, [arg1, [arg2 ...]]);
Here in question array like is html element collection; and it takes items without any styling.
list is assigned a collection of elements that are children of the raffles-list element
list is then reassigned by filtering its elements as follows
an empty array is filtered by calling it with the parameter list and a callback function. The formal parameters for call are this (which is the list) and optionally further objects (in this case a callback function)
The callback function receives a formal parameter j and is called for each element
If the element's value for the style attribute is empty the element is retained in the array. Otherwise it is discarded.
At the end list should contain all elements that don't have a value for its style attribute

Function param array, how to affect reference = [] or reference.concat(array2)? [duplicate]

This question already has an answer here:
Mutate JavaScript Array Inside Function
(1 answer)
Closed 8 years ago.
So it could just be I'm crazy tired but I can't seem to figure this out.
I've been picking up javascript which I'm finding horrible coming from actionscript 3 where everything was typed. I had a function that referenced two array variables directly, I later needed to use it again for a different data set so I've altered it to take parameters and now it's breaking.
I have one array full of elements, the 2nd is empty. When I call the function, a random element is removed from the first array and pushed into the 2nd array, that element is also returned by the function. If the 1st array is empty I have concat the 2nd array to fill it back up. The goal was to randomly iterate through the elements and not have the selected elements show up again until I had finished a full cycle.
Prior to concat I was using slice(which should work just as well?), the problem I believe is that I know have a parameter that is redefined when I do 'array = array2.slice()', concat doesn't seem to work around that. I don't know if returning the single sliced element from the first array is bad if I'm expecting a string, I think slice is returning an array with the single element, easy fix there though by adding [0] to the return statement.
Heres the code:
//Gets a random element from array, that element is moved from the 'src' array to the 'bin' array,
//this allows random selection without choosing the same element until all of 'src' array elements have been picked
function getRandomElement(array_src,array_bin){
//Randomly selects a tweet from the que, then stores it in another array so each tweet shows once before recycling
if(array_src.length==0 && array_bin.length>0) {array_src.concat(array_bin);} //Recycles array elements when the src array is empty
var randomElement = array_src.splice(Math.floor(Math.random()*array_src.length),1); //Grab a random array element
array_bin.push(randomElement);//array elements stored here to be recycled
return randomElement;
}
I think I could maybe use an object with two properties pointing to the arrays and pass those in, though it'd be nicer if there is a better way. I could also use push on array_src looping through the array_bin to work around that issue if there isn't any other way.
I wouldn't say this is a duplicate Felix. The answer you provided is pretty much the same, but the question itself is phrased differently, I wasn't aware of the term mutate, finding the question/answer wouldn't be easy, none of the suggested links SO provided were relevant. Worth keeping up for making the answer more discoverable to those unaware of the mutate term.
I have a hard time understanding the problem, but I think you are wondering why array_src.concat(array_bin) doesn't seem to do anything?
That's because .concat returns a new array. If you want to mutate the existing array_src array, you can use .push:
array_src.push.apply(array_src, array_bin);
FWIW, this has nothing to do with strong typing. JavaScript (and I guess ActionScript as well), is pass-by-value. That implies that assigning a new value to array_src doesn't change the value of the variable that was passed to getRandomElement.
But since arrays are mutable in JavaScript (and ActionScript I assume), you can mutate the array itself.

How can I copy element by 'pass by value' not by 'pass by reference'

Below is the snippet of the code. Basically, 'this.leaves' is a array. And I want to shift first array element, make copy of it (called frontLeaf), and unshift it to the original array, change some attributes from copied element, and put that element to the parent array element.
var frontLeaf = this.leaves.shift();
this.leaves.unshift(frontLeaf);
frontLeaf.leftChild = tmp;
frontLeaf.rightChild = this;
this.parent.leaves.push(frontLeaf);
My problem is that frontLeaf seems to be passed by reference that when I assign
frontLeaf.leftChild = tmp;
frontLeaf.rightChild = this;
above two lines of code seems to affect both elements in this.leaves and this.parent.leaves... So, How can I resolve this problem?
Javascript passes all objects by reference. The only way to do what you're looking for is to create an entirely new object, do a deep copy and then push it.
See this post for a sample solution using jQuery.
Yes, in JavaScript objects are always passed by reference. If you want a copy of an object, you'll have to write a deep-copy routine yourself.
I'm not sure exactly what you're trying to do (what is tmp? what is this? what is this.leaves an array of?), but maybe there is a way to do it without needing a copy?
Here's what I did when faced the same issue:
var newObj = JSON.parse(JSON.stringify(oldObj));

Categories