Remove element from nested object - javascript

I have following object:
{"2":{"cid":"2","uid":"2"},"1":{"cid":"1","uid":"3"}}
In this example I want to remove
"1":{"cid":"1","uid":"3"}
from it.
I have tried all solutions that I found on Stack Overflow, and could not make any of them work. I am mostly PHP person, so I might miss something important here?

Just use delete with the appropriate property.
var obj = {"2":{"cid":"2","uid":"2"},"1":{"cid":"1","uid":"3"}};
delete obj["1"];
Note the " around the 1 to mark it as an identifier and not as an array index!
EDIT
As pointed out in the comment, obj is an object and no array no matter how you address the [1] property. My last note was just to make it clear that you are working with an object and not an array.
In my experience most people associate integer properties with arrays and string properties with objects. So I thought it might be more helpful to highlight the property in the way given.

var myObj= {"2":{"cid":"2","uid":"2"},"1":{"cid":"1","uid":"3"}}
delete myObj['1'];
alert ( myObj['1']);
please notice there are Cross platform problems with delete :
Cross-browser issues
Although ECMAScript makes iteration order of objects
implementation-dependent, it may appear that all major browsers
support an iteration order based on the earliest added property coming
first (at least for properties not on the prototype). However, in the
case of Internet Explorer, when one uses delete on a property, some
confusing behavior results, preventing other browsers from using
simple objects like object literals as ordered associative arrays. In
Explorer, while the property value is indeed set to undefined, if one
later adds back a property with the same name, the property will be
iterated in its old position--not at the end of the iteration sequence
as one might expect after having deleted the property and then added
it back.

var arr=[[10,20,30],[40,50,60],[70,80,90]];
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr[i].length;j++){
if(arr[i][j]==50){
arr[i].splice(j,1);
}
}
}
document.write(arr);

JavaScript doesn't have multi dimensional Arrays, only arrays and objects. That said: delete theObject['1']; should work just fine

You could use delete in javascript
Ex:
var x = {"2":{"cid":"2","uid":"2"},"1":{"cid":"1","uid":"3"}};
delete x['1'];
Also, check this:
Deleting Objects in JavaScript

Assign your Object (not an Array) to a variable, this way:
var o = {"2":{"cid":"2","uid":"2"},"1":{"cid":"1","uid":"3"}};
Then do:
delete o['1'];
That's it!

Related

Is it impossible to use the item() method for getting of array item?

I learn JavaScript through the "JavaScript & jQuery" book by John Duckett (Russian translate).
Author writes two code examples of array item getting:
var colors = ["white", "black","custom"];
var el = document.getElementById('colors');
el.textContent = colors[0];
and
var colors = new Array("white", "black","custom");
var el = document.getElementById('colors');
el.innerHTML = colors.item(0);
In the article he wrotes that for getting of array item can be used item() method. But in the code sources he uses colors[0] instead of colors.item(0) in the second variant.
I see that colors.item(0) doesn't work. Is it wrong info?
JavaScript arrays are specialised objects, which have a particular behaviour and a particular set of methods. .item() is not one of them.
There are many other JavaScript objects which also contain a collection of values. Some of these objects include an .item() method.
The thing is, even though these objects may have some similarity with arrays in that they contain a collection of values, they’re not the same. Arrays, have some features, and these other objects have some others.
To learn more about what JavaScript arrays do have, you can look at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
In principal, it would be possible to add an .item() method to arrays by adding to the Array prototype. However, it is certainly not a natural part of JavaScript arrays.
Edit
One of the important properties of the array is in how it is accessed: you can read, replace or create an item using the square brackets ([]). Non-array collections don’t have this feature, so the items need to be accessed with a dedicated method.
Another important property is that the .length property is automatically updated.
Yes, it looks like a mistake in the book. The Array class doesn't have an item method. colors[i] should be used to get an element at a specified index.

how does javascript move to a specific index in an array?

This is more a general question about the inner workings of the language. I was wondering how javascript gets the value of an index. For example when you write array[index] does it loop through the array till it finds it? or by some other means? the reason I ask is because I have written some code where I am looping through arrays to match values and find points on a grid, I am wondering if performance would be increased by creating and array like array[gridX][gridY] or if it will make a difference. what I am doing now is going through a flat array of objects with gridpoints as properties like this:
var array = [{x:1,y:3}];
then looping through and using those coordinates within the object properties to identify and use the values contained in the object.
my thought is that by implementing a multidimensional grid it would access them more directly as can specify a gridpoint by saying array[1][3] instead of looping through and doing:
for ( var a = 0; a < array.length; a += 1 ){
if( array[a].x === 1 && array[a].y === 3 ){
return array[a];
}
}
or something of the like.
any insight would be appreciated, thanks!
For example when you write array[index] does it loop through the array till it finds it? or by some other means?
This is implementation defined. Javascript can have both numeric and string keys and the very first Javascript implementations did do this slow looping to access things.
However, nowadays most browsers are more efficient and store arrays in two parts, a packed array for numeric indexes and a hash table for the rest. This means that accessing a numeric index (for dense arrays without holes) is O(1) and accessing string keys and sparse arrays is done via hash tables.
I am wondering if performance would be increased by creating and array like array[gridX][gridY] or if it will make a difference. what I am doing now is going through a flat array of objects with gridpoints as properties like this array[{x:1,y:3}]
Go with the 2 dimension array. Its a much simpler solution and is most likely going to be efficient enough for you.
Another reason to do this is that when you use an object as an array index what actually happens is that the object is converted to a string and then that string is used as a hash table key. So array[{x:1,y:3}] is actually array["[object Object]"]. If you really wanted, you could override the toString method so not all grid points serialize to the same value, but I don't think its worth the trouble.
Whether it's an array or an object, the underlying structure in any modern javascript engine is a hashtable. Need to prove it? Allocate an array of 1000000000 elements and notice the speed and lack of memory growth. Javascript arrays are a special case of Object that provides a length method and restricts the keys to integers, but it's sparse.
So, you are really chaining hashtables together. When you nest tables, as in a[x][y], you creating multiple hashtables, and it will require multiple visits to resolve an object.
But which is faster? Here is a jsperf testing the speed of allocation and access, respectively:
http://jsperf.com/hash-tables-2d-versus-1d
http://jsperf.com/hash-tables-2d-versus-1d/2
On my machines, the nested approach is faster.
Intuition is no match for the profiler.
Update: It was pointed out that in some limited instances, arrays really are arrays underneath. But since arrays are specialized objects, you'll find that in these same instances, objects are implemented as arrays as well (i.e., {0:'hello', 1:'world'} is internally implemented as an array. But this shouldn't frighten you from using arrays with trillions of elements, because that special case will be discarded once it no longer makes sense.
To answer your initial question, in JavaScript, arrays are nothing more than a specialized type of object. If you set up an new Array like this:
var someArray = new Array(1, 2, 3);
You end up with an Array object with a structure that looks more-or-less, like this (Note: this is strictly in regards to the data that it is storing . . . there is a LOT more to an Array object):
someArray = {
0: 1,
1: 2,
2: 3
}
What the Array object does add to the equation, though, is built in operations that allow you to interact with it in the [1, 2, 3] concept that you are used to. push() for example, will use the array's length property to figure out where the next value should be added, creates the value in that position, and increments the length property.
However (getting back to the original question), there is nothing in the array structure that is any different when it comes to accessing the values that it stores than any other property. There is no inherent looping or anything like that . . . accessing someArray[0] is essentially the same as accessing someArray.length.
In fact, the only reason that you have to access standard array values using the someArray[N] format is that, the stored array values are number-indexed, and you cannot directly access object properties that begin with a number using the "dot" technique (i.e., someArray.0 is invalid, someArray[0] is not).
Now, admittedly, that is a pretty simplistic view of the Array object in JavaScript, but, for the purposes of your question, it should be enough. If you want to know more about the inner workings, there is TONS of information to be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
single dimension hash table with direct access:
var array = {
x1y3: 999,
x10y100: 0
};
function getValue(x, y) {
return array['x' + x + 'y' + y];
}

Trouble with "dictionary" creation in JavaScript

OK, first-off let me tell you that I'm too far from being considered experienced in JavaScript... (perhaps I'm even trying to implement something not actually supported by the language?).
So... here we are...
I want to create a structure like this (it's just an illustrative example) :
Addresses
--- John
--- Phone
--- Address
--- Peter
--- Phone
--- Address
So, I've seen (or perhaps I'm just guessing) that I can do something like that (I've run all my tests in Chrome's JavaScript console) :
var addresses = [];
addresses["John"] = {};
addresses["John"].Phone = "12312312312";
// And so on...
However :
If I do addresses['123'] = {}; then a proper 124-entry array is constructed.
If I do addresses['somestring'] = {}; then addresses remains an empty array [].
What am I doing wrong? Is there no native support for proper dictionaries (or map - no matter how this thing is called) in JavaScript?
Please note: I want to be able to progressively add entries to addresses, as well as keys to each address entry (and not just create it in one-shot).
You are creating an array, but then you are using it as an object instead (which is possible because an array happens to be an object). To contain properties rather than numbered indices, you should use an object:
var addresses = {};
addresses["Holmes"] = { Phone: "14", Address: "Baker street 221b" };
JavaScript has Objects and Arrays.
Arrays are a type of Object that treats properties with numerical with special significance. It will have a length property based on the highest value property name (that is a number), and it has methods such as push, pop and forEach to manipulate its numerical members based on their number.
If I do addresses['123'] = {}; then a proper 124-entry array is constructed.
You already have an array. That just adds a member called 123 to it and updates its length.
If I do addresses['somestring'] = {};
This will add that member to the array, but it won't appear in any of the regular means of accessing array members. You have to access it by name.
Don't give named properties to arrays. Use a plain object.
Is there no native support for proper dictionaries
An object is as close as you can get.
If you want something ordered use an array with numerical properties.
If you want something with named keys, use an object.
When you do this addresses['somestring'] = {}; you wil get an empty array because {} you are assigning an empty object.
Rather if you do addresses["dd"] = {s: "s"} the addresses will have the object
Javascript does not have dictionaries or maps or associative arrays.
It does, however, have objects which can be quite similar. (They can also be quite different, so that is essential to know.)
To make things more confusing, an array is an object. You can put random properties on an array and it will work -- like an object.
Javascript arrays take integer[*] indexes and adjust the .length property.
Objects take string property names. This is important: If you use something that is not a string, it will be converted into one .. usually called [Object object]
Might want to read this:
http://eloquentjavascript.net/chapter4.html
[*] Yea, yea, yea -- they are really strings behind the scenes. It is easier to think of them as integers and avoid that grief.

How do modern browsers implement JS Array, specifically adding elements?

By this I mean when calling .push() on an Array object and JavaScript increases the capacity (in number of elements) of the underlying "array". Also, if there is a good resource for finding this sort of information for JS, that would be helpful to include.
edit
It seems that the JS Array is like an object literal with special properties. However, I'm interested in a lower level of detail--how browsers implement this in their respective JS engines.
There cannot be any single correct answer to this qurstion. An array's mechanism for expanding is an internal implementation detail and can vary from one JS implementation to another. In fact, the Tamarin engine has two different implementations used internally for arrays depending on if it determines if the array is going to be sequential or sparse.
This answer is wrong. Please see #Samuel Neff's answer and the following resources:
http://news.qooxdoo.org/javascript-array-performance-oddities-characteristics
http://jsperf.com/array-popuplation-direction
Arrays in JavaScript don't have a capacity since they aren't real arrays. They're actually just object hashes with a length property and properties of "0", "1", "2", etc. When you do .push() on an array, it effectively does:
ary[ ary.length++ ] = the_new_element; // set via hash
Javascript does include a mechanism to declare the length of your array like:
var foo = new Array(3);
alert(foo.length); // alerts 3
But since arrays are dynamic in javascript there is no reason to do this, you don't have to manually allocate your arrays. The above example does not create a fixed length array, just initializes it with 3 undefined elements.
// Edit: I either misread your question or you changed it, sorry I don't think this is what you were asking.

How come setting value in one array key is setting in another key?

I have an array of objects with various objects within to hold UI values. I wanted to have a button so that element 0's values are replicated through the whole array. However I noticed that setting one set them all. Here is an example without using any looping:
console.log('manual 3: ', lis[3].spacer.divider.type); // prints 'none'
lis[1].spacer.divider.type = 'bananas';
console.log('manual 3: ', lis[3].spacer.divider.type); // prints 'bananas'
I am completely baffled how setting lis[1] also set lis[3]
They must both be references to the same object.
If they're DOM nodes, you can copy them using cloneNode().
Watch out for IE bugs - it has a habit of not cloning properly (for example cloning a <select> doesn't maintain the selectedIndex).
See also What is the most efficent way to clone a JavaScript object? for cloning objects.
Because the variables are reference variables and they all reference the same object and as a result it looks like changing one changes all of them, really they are all the same underlying object.
If you want lots of unique arrays they should all be created as a fresh or be clones of each other.
It turns out I was referencing the same object. Thanks. It didn't click to me since all the other objects above (spacer,lis) were unique. I accidentally was setting divider to a member default of spacer instead of a function returning the default.
Thanks!

Categories

Resources