push associative array error? - javascript

I have to push elements in an associative array from another array after some processing and I'm doing something this:
for(var i in this.aNames) {
var a = this.aNames[i];
// some processing on a
aList[i] = a;
aList.push(i);
}
But it's not giving me the proper array.
EDIT :
Here aNames is an associative array like this
'1232':'asdasdasd',
'6578':'dasdasdas'
...... and so on of about 100 elements.
I'm using for here as I want to do some changes in every element of the array.
Then I'm displaying the result array on the page but it's showing the key value together with the array data.
I.e. it should only display asdasdasd or asdasdasd but it's displaying keys too, like 1232 asdasdasd 6578 dasdasdas.

There are multiple things which may go wrong...
Primarily, make sure that this is pointing to the correct context and that this.aNames is actually returning a complex object (associative array).
Also, what's aList? Is it an array? If it is, push should append your array with the key of the current member (the member's name).
If you want to append the values of the members on your source object, you need to do something like this:
var obj = {name: 'dreas'},
arr = []; // arr is an array
arr.push(obj["name"]); // arr now contains a single element, 'dreas'
In your for..in construct, you are both adding elements to an alleged array (aList) with push but also creating new members on your array (with the subscript notation, aList[i] = "asd" since i in this case (for..in iteration) refers to the member's name).
So, what you need to do is decide if you want to add elements to an array or members to an object, not both.
If you just want to clone an array, use a for loop. If on the other hand you want to clone an object, it's not that trivial because members can also be complex objects containing their own members, and simply doing arr[i] = obj.member will only copy a pointer to arr[i] if member is a complext object, not a value type.
Just to make sure my terminology is understandable:
var anObject = {name: "dreas"},
anArray = [1,2,3];
anObject["name"] <= member (results in "dreas")
anArray[1] <= element (results in 2)

Related

Issue when splicing array of objects

I have a vue application that gets a set of objects from an external REST API.
In a component, I sort and filter the object into an array of objects based on a field called rank, like this:
let myResults = _.orderBy(this.search_result, 'rank', 'desc').filter(service => (service.rank >= 5) ? service: "");
I then need to move a single element/object to the end of the list before rendering it, however, when I tried to do this:
let index = myResults.findIndex(e => e.name === 'Target Element');
myResults.push(myResults.splice(index,1));
It didn't work; It pushed an empty element back to the list. Eventually, I got it working by doing the following:
myResults.push(myResults.splice(index,1)[0]);
I noticed the splice was creating an array that looked like [object, object] with all the target object in the zero index object.
I don't really understand why this happened. Have I done something to the original object somewhere or is this a vue thing?
JavaScript Array.prototype.splice() returns an Array.
Return value
An array containing the deleted elements.
If only one element is removed, an array of one element is returned.
If no elements are removed, an empty array is returned.
Since an Array is returned, you're .push()-ing and Array into an existent array. As you noticed correctly, you need to extract that one Object using removedItems[0], making
myResults.push(myResults.splice(index,1)[0]);
or equally
// Remove from array 1 item
const removedItems = myResults.splice(index, 1); // Array of removed items
// Get the first Object from array
const item = removedItems[0]; // Object
// Append one Object
myResults.push(item);
the correct approach.

Empty Array in javascript

I created an object which contains an array.
I noticed that when I dont enter any values into the array, it still has one - its size,
So how can I check if the array is actually empty?
Here's how I'm creating the array:
array = { text:[10] }
The size of the array is not an array entry (aka array "element"). It is a property, length, but it's not an entry. An empty array is exactly that: empty.
The code you posted in a comment:
array = { text:[10] }
does not create an empty array. It creates an array of length 1 with the entry 10 in it.
If you want to create an empty array with a specific length, you can't do that in a single statement with an array literal ([]). You have two ways you can do it:
Using an array literal and assigning to length:
var a = [];
a.length = 10;
or using new Array:
var a = new Array(10);
But there's virtually never any reason, in JavaScript, to predefine the length of the array, because standard JavaScript arrays aren't really arrays at all. It does make sense with the new typed arrays (Uint32Array and such), and to do it you have to use the array constructor (new Uint32Array(10)).

Trouble with basic Javascript

I haven't touched Javascript in a while and now I'm having trouble with basic arrays.
params=new Array();
params['return']='json';
alert(params.length);
This always returns 0 when I'm expecting 1. What's wrong with this?
Arrays use numerical indexes. When you use a string "index", it just adds a new property to the array object, but the new value isn't in the array.
Thus, the array is still empty, but you can access your value as you could with any other object.
Your code is equivalent to
var params = {}; //new object (not array)
params['return']='json'; //new property added to object
A few things:
You forgot var:
var params = new Array();
But an array takes numeric indices, so params['return'] is not really a member of the array but of the object that represents the array, so it doesn't affect the length.
You could use an object but objects have no length:
var params = {};
params['return'] = 'json';
To get the length though you can count the keys in that object and get the length of the resulting array:
var len = Object.keys(params).length;
Javascript arrays don't hold key value pairs like objects do, so the length isn't incremented when you assign a value. They are however objects themselves, so you can assign values to its properties (in this case the return property).
You probably want params to be a plain object: params = {}
You need to count the properties, like this for example:
function dictionarySize(dict){
var size = 0;
for (key in dict){
// In practice you'd probably want to filter using hasOwnProperty
size++;
}
return size
}
alert(dictionarySize(params));
Or using a library like underscore.js:
_.size(params);
Object.keys is also an option, although it won't work in IE8 and older.
If you don't need an key value pairs use params.push:
params=new Array();
params.push('json')
alert(params.length); // 1
You can create an array, push stuff on it, and assign properties to values of it like so:
var params=[];
params.push('firstly');
params[0]="jonson";
params['return']="fredy"
params.newone="json";
params.push('Carl');
NOW, if you do:
console.log(params.length,params);
the result of that is:
2 ["jonson", "Carl", return: "fredy", newone: "json"]
SO, you see "firstly" was replaced by "jonson" in the [0] - so the "pushed" value is addresed by the numerical [0]

Javascript multidimensional arrays with alphanumeric keys

This seems to be a common source of confusion from what I've seen, and apparently I'm no exception. I've read a few tutorials on this, and I still can't quite get my head around it. From what I can gather, Arrays are objects in Javascript, just like Strings and other variable types. But I still don't get how that helps me declare a multidimensional array with alphanumeric keys.
In PHP I can simply write:
$calendar = array();
foreach ($schedule->currentExhibitions as $key) {
$calendar[$key["ExhibitionID"]]["startDate"] = date("Y,n,j", strtotime($exhibition["StartDate"]));
$calendar[$key["ExhibitionID"]]["endDate"] = date("Y,n,j", strtotime($exhibition["StartDate"]));
}
But in Javascript trying something similar will create errors. Should I create an Array and fill it will Objects? If so, how would I go about doing so? Or should I just use an Object entirely and skip having any sort of Array? (If so, how do I create a multidimensional Object?)
Sorry for the newbish quesion!
If your keys are strictly numerical and ordered starting at zero, then an array makes sense and you can use square bracket notation just like you would in php, although you will need to initialize sub-arrays if you want to have multiple dimensions :
var myArray = [];
myArray[0] = [];
myArray[0][0] = "something interesting";
If your keys are not numerical, ordered and starting at zero, then you should use an object (all keys are strings), which still allows the square bracket notation :
var myObject = {};
myObject["1A"] = {};
myObject["1A"]["3B"] = "something interesting";
In Javascript, an array is an object, who's keys are numerical, sequential, indexes.
As soon as you want to use alpha-numerica (aka strings) keys, you use a regular object.
In JS to do what you want, you'd do the following (using more or less your php code).
var calendar = {};
Object.keys(schedule.currentExhibitions).forEach(function(key) {
var ex = schedule.currentExhibitions[key];
calendar[ex.exhibitionId] = calendar[ex.exhibitionId] || {}; //if the key doesn't exist, create it.
calendar[ex.exhibitionId].startDate = date(); //some js date function here
calendar[ex.exhibitionId].endDate = date(); //your js date function here
});
I look at Multidimension as nesting, and at multiple levels of nestings as complex objects. For example:
var parent = [];//top holder
var child1 = {};
child1.name = "Jim";
parent.push(child1);
In this simple example, you can access child1 like this:
parent[0]["name"] //Jim
So that is, in a way, multidemensional. Instead of using ["name"] as an indexer, or child1 as an object it could also be an array, like this:
var parent = [];//top holder
var child1 = [];
child1.push("Jim");
parent.push(child1);
In this example, you could get Jim with:
parent[0][0];//Jim
So for complex examples you may have multiple levels of these nestings (or dimensions).
parent[0]["Child"].grandChild[5]["cousin"].name //etc
Where that would just be a continuation of the previous examples down the line.
If you want to preserve order or you want to access by numeric index, use an array. The value of the array can be a single value or an object or array itself (so each value in the array can contain more than a simple value).
If you want to access by a unique alphanumeric key, then use an object and assign properties to it.
Arrays have numeric indexes. They do not have alphanumeric indexes.
Objects have string keys.
Because an array is also an object, it can have both types of keys, but using a string key is not an array access, it's accessing a property of the object.
When you ask for the .length of an array, you only get the length of the numeric indexes. It does not include other properties of the object.
An array of objects is a very practical data structure in javascript and is used quite often when either order or index by numeric index is important.
If order is not important or you don't need to access by numeric index and just want to access by an alpha numeric string, then you should just use an object and set a properties on it with keys that are your alphanumeric string.

Javascript array index

Sorry for asking a noob question but if I have an array:
MyArray["2cd"]="blah1";
MyArray["3cx"]="blah3";
MyArray["8cz"]="blah2";
And a string myStr="2cd";
And then I use MyArray[myStr] to get the value of blah, how can I get the number I am accessing in the object/array or 0 in this case?
If I may read between the lines, it sounds like you're thinking that the code you posted:
MyArray["2cd"] = "blah1";
MyArray["3cx"] = "blah3";
MyArray["8cz"] = "blah2";
will automatically become the equivalent of:
MyArray[0] = MyArray["2cd"] = "blah1";
MyArray[1] = MyArray["3cx"] = "blah3";
MyArray[2] = MyArray["8cz"] = "blah2";
and therefore you can get the string "blah1" either of these two ways:
var foo = MyArray[0]; // sets foo to "blah1"
var bar = MyArray["2cd"] // also sets bar to "blah1"
But that's not how JavaScript works.
You certainly can set things up so you can use my MyArray[0] and MyArray["2cd"] to fetch the same value, but you have to do it explicitly as in my example.
One thing you didn't mention is how you declared MyArray itself. Is it an Array or an Object? That is, before the code you posted, did you create MyArray with:
var MyArray = {}; // or equivalently, var Array = new Object;
or:
var MyArray = []; // or equivalently, var Array = new Array;
The first example creates an Object, the second an Array.
What is a bit confusing is that JavaScript has both of these two types, which in many cases you can use somewhat interchangeably. But it's customary to use an Object when you are using arbitrary (generally but not necessarily non-numeric) keys into the object, as in your example. Conversely, it's customary to use an Array when you are primarily using strictly numeric indexes.
In fact, JavaScript's Array type inherits from the Object type. An Array is simply an Object with some additional behavior:
An Array has additional methods such as .push() which appends an item to the array.
An Array has a .length property which is automatically updated when you add elements with .push() or a direct array[123] assignment, or when you remove elements with .pop() or other methods.
What JavaScript doesn't have, as Fabrício pointed out, is an "associative array" that behaves like what you might find in some other languages. It has Objects and it has Arrays (which inherit from Objects), and you have to deal with each of those on their own terms.

Categories