javascript: multidimensional array manipulation - javascript

I have something like this (data should be a global variable):
var data = {
fields:{
id: 0,
ticket: 0,
description: 0,
}
}
Now I want to use something like this to change these variables:
function toggleStatus(element) {
data[fields][element] = 1;
}
This doesn't work, of course, but what is the correct way to manipulate data in similar fashion?
Basically, I need to create a multidimensional array that changes it's status based on user input.

That should work fine, but you have to enclose fields in quotes:
data['fields'][element] = 1;
Or
data.fields[element] = 1;

if element is passed in as one of the names of the properties of field, this should work.
Try:
data['fields']['id'] = 1;
Maybe this would work?

just a note, if you're dealing with arrays of objects, it would look more like this:
var data = [{
fields:[{
id: 0,
ticket: 0,
description: "bar"
},
{
id: 1,
ticket: 1,
description: "foo"
}]
}];
then you could access the properties like
data[0].fields[0].id
data[0].fields[1].description = "more foo"
or
data[0].fields[1]['description'] = "more foo"

Related

javascript dynamic structure with array or object

Im trying to create a structure with Javascript as follows:
var users = {
user.id: {
session.id1: session.id1,
session.id2: session.id2,
session.id3: session.id3
},
user.id2: {
session.id1: session.id1,
session.id2: session.id2,
session.id3: session.id3
},
};
What i need: add new sessions and remove them, removing okay, but how should i define object and how can i push new sessions to user obejct? That's why key is equal to value.
If you want to use session.id1 instead of something like sessionId1 :
Assign value:
users['user.id'].['session.id1'] = value;
Create object:
var users = {
'user.id': {
'session.id1': session.id1,
'session.id2': session.id2,
'session.id3': session.id3
},
'user.id2': {
'session.id1': session.id1,
'session.id2': session.id2,
'session.id3': session.id3
},
};
But I don't recommend it. If you are the only one who is gonna work with this code, it's ok.
You can first create an empty object and fill it as and when the data comes like
users[user.id] = {};
For an example:
var users = {};
var user = {id : 1}; //Data received(Just an example)
users[user.id] = {};
var session = {id1 : 1.1}; //Data received
users[user.id][session.id1] = session.id1;
console.log(JSON.stringify(users));
How about refactoring the user object to store sessions as an array and push, pop and slice them as required.
var users = [
{
id:'userid',
sessions: [
{
id: 'sessionid',
sessiondata: something
},
{
id: 'sessionid',
sessiondata: something
}
]
}];
This way to can just use normal array operators on the session array for each user.

How to convert a bunch of arrays into a single object?

Here is what im doing:
onClick, grab details immediate subnodes and publish it on html. Status = DONE // This works well
NOW, I am using a bunch of arrays to get this done.
node.eachSubnode(function(node) {
title[title.length] = node.name; // This is what i want to modify
data[data.length] = node.data; // This is what i want to modify
});
Here is how they look currently:
title = ['Coffee', 'Tea'];
data = ["Americans", "Britishers"]; // i use a loop to iterate through these arrays and append to html.
Here is what i want it to be:
var preference = {
title: 'Coffee',
data: 'Americans'
},
{
title: 'Tea',
data: 'Americans
}
I want to create this using the node.eachSubnode loop.
I'm not sure if I understood correctly, but I think this is what you want:
var preferences = [];
node.eachSubnode(function(node) {
preferences.push({
title: node.name,
data: node.data.germ
});
});
You cannot create an object that looks exactly like that, I think you need an array with objects. Assuming your node is an array with the length property, this method is the fastest.
var preference = new Array(node.length||0), i = 0;
node.eachSubnode(function(node) {
preference[i++] = {
title: node.name,
data: node.data.germ
};
});

Get the lower integer id not already used in Javascript

I have a list of JS objects defined by an integer ID.
objects = [{
id: 0,
type: 'null'
}, {
id: 1,
type: 'foo'
}, {
id: 2,
type: 'bar'
}];
I implemented a function to remove an element from my list :
removeObject = function(o){
objects.splice(objects.indexOf(o), 1);
}
My problem is that I need to create a function to add a new item in my list with a id not already used (for example the lower positive integer not present in the list).
I tried to do something like that but it did not work when I remove the object 0 (for example).
addObject = function(type){
objects.push({
id: objects.length,
type: type
});
};
How can I do this ?
EDIT 1
According to your answers, I assume that the best solution in term of performance is to just use a topId which is always incremented when I add a new object in my list.
But that do not answer to my requierement. Actually I think that #X-Pippes response could be good.
Should I do someting like that :
objects = [{
id: 0,
type: 'null'
}, {
id: 1,
type: 'foo'
}, {
id: 2,
type: 'bar'
}];
// Init available ids list with the default value
availableIds = [objects.length];
removeObject = function(o){
// Remove the object from the list
objects.splice(objects.indexOf(o), 1);
// Add its id to the available ids list
availableIds.push(o.id);
}
addObject = function(type){
// Get lower id available
var newId = Math.min.apply(Math,availableIds);
// Push the new object with the id retrieved
objects.push({
id: newId,
type: type
});
// Remove used id from the available ids list
availableIds.splice(availableIds.indexOf(newId), 1);
// Add a default id if available list is empty
if(availableIds.length < 1) availableIds.push(objects.length);
};
if you remove for instance 0 and the next addObject is 0 you have to do something like:
keep a list [initial empty] with every ID removed. When you need to add a new one, pick the shorter, add and delete from list.
Also keep a var with the biggest ID added. If the previous list is empty, add +1 to the var and addObject with that id
Use the correct structures. A JavaScript object will do the job. It guarantees that you only get one item for key, you can look up and remove by key in probably O(1)ish. No point trying to re-implement it in a less efficient manner, which will be O(n) lookup.
var structure = {
objects : {},
topId : 0
}
structure.add = function(item) {
var id = this.topId ++;
structure.objects[id] = item;
}
structure.add("thing")
structure.add("other thing")
structure.add("another thing")
structure.objects
>>> Object {0: "thing", 1: "other thing", 2: "another thing"}
structure.objects[1]
>> "other thing"
Then the normal index operations to get/set/delete.
If you use that function then you have an invariant (guarantee) on your data structure that you won't use the same ID twice.
You need a function to find the first free number:
addObject = function(type){
objects.push({
id: firstOpenIndex(),
type: type
});
};
firstOpenIndex = function() {
for(var idx = 0; true; i++) {
var found = false;
for(var o in objects) {
if (objects[o].id == idx) {
found = true;
break;
}
}
if (!found) return idx;
}
}
In Javascript MaxInt is 9007199254740992. Why not just keep incrementing?
You can and probably should just use an array(s) like:
objects.type=['null','foo','bar'];
to add an object see:
How to append something to an array?
to find a value: var index = objects.type.indexOf('foo');
to find 1st empty field var index = objects.type.indexOf(''); which you can use to find the element for adding (if index is -1 use objects.type.length) if you "delete" an element by setting it to "" or... unless you have specific reason for keeping the "ID" static (in this case the array index), remove the element and only append new ones to the end
to remove an element see:
How do I remove a particular element from an array in JavaScript?
which will allow you to just push/append the next data.
if you need a new object array with empty fields to fill because you get new data to track:
object.newField=new Array(objects.type.length);
If you get to this point where your object contains multiple arrays, you will probably want to create functions for insert/add and delete/remove, so you don't do an operation on 1 and not the other.
Everything is already built in (read likely already pretty fast) and you don't need to reinvent constructors for your really cool object type.

javascript array in array

I am building a file management system for the web right now.
But I have some problems with javascript array's.
In the system there is an opportunity to add labels to file's.
In javascript I want to have the ID and the value's of the labels with the fileId in 1 array.(as below).
I also want the FileId and the LabelId not as the index of the array's. Because the FileId and labelId can be a realy high number. And then I have an array full of undefined items.
Here an example of how I would like to have it:
array[FileId][labelId,labelValue]
If you have an solution please help me.
Thanks.
You can form structure like this:
arr = [{FieldId:fid_value, Labels:[{labelId:lid_value, labelValue:label_text}]}]
Basically, an array with objects. Each object contains two fields: field id and labels.
Labels is an array with objects also. Each object has label id and label value property.
Code to create new items might be like this:
arr = array();
fieldObj = {FieldId:fid_value, Labels:[]};
fieldObj.Labels.push({labelId:lid_value, labelValue:label_text});
fieldObj.Labels.push({labelId:lid_value, labelValue:label_text});
fieldObj.Labels.push({labelId:lid_value, labelValue:label_text});
...
arr.push(fieldObj);
I'm not entirely sure what you're asking but array within array is possible...
a = []
a.push('a')
Result:
["a"]
a.push(['hello','world'])
Result:
["a",
Array[2]
0: "hello"
1: "world"
]
It sounds like you want objects instead of arrays:
var obj = {};
obj["fieldName"] = {label: "labelname", labelId: 1234};
Then you can access this data as:
obj["fieldName"].label
You could also use an object
var data = {};
data["item1"] = { "labelId" : "foo1", "labelValue" : "bar1" };
data["item2"] = { "labelId" : "foo2", "labelValue" : "bar2" };
console.log(data.item1.labelId);
There are plenty of ways you can strcture the object, it is normally better to use an object than to remember that index 0 is the id and that index 1 is a value.
Use should use objects as well as arrays:
var root = [{
id: '12345',
metadata: {
label: 'foo',
},
type: 'folder',
name: 'Folder Name',
children: [...]
}
];
Now, you can iterate through the folders and files in your root:
for (var i = 0; i < root.length; i++) {
var item = root[i];
console.log(item.type, item.name, item.id);
}

How to build a json object with a loop?

I'm trying to loop through a number of items, and create a json object. Each loop should be a new item on the object, but I'm having some issues doing it. It seems that only one set of items gets added, instead of multiple ones.
Here is my code:
jsonObj = {}
rows.each(function (index) {
jsonObj["id"] = $this.find('.elementOne').val();
jsonObj["name"] = $this.find('.elementTwo').text();
});
Here is what my json looks like:
{
id: "3"
name: "Stuff"
},
Here is what I am trying to do:
{
id: "1"
name: "Stuff"
},
{
id: "2"
name: "Stuff"
},
{
id: "3"
name: "Stuff"
}
There is no JSON here. Please don't confuse:
A JavaScript object (a data structure)
A JavaScript object literal (code to create such a data structure)
JSON (a data format based on a subset of object literal notation)
If you want an ordered list of objects (or any other kind of JavaScript data structure) then use an array. Arrays have a push method.
var myData = [];
rows.each(function (index) {
var obj = {
id: $this.find('.elementOne').val(),
name: $this.find('.elementTwo').text()
};
myData.push(obj);
});
You override the object instead of adding it a new value each iteration.
Fixed code using an array:
jsonObj = [];
rows.each(function(index) {
jsonObj.push({
'id': $this.find('.elementOne').val(),
'name': $this.find('.elementTwo').text()
});
});​
What you want is an array of objects. When you try to write the same property on the same object multiple times, it gets overwritten which is why you're seeing id and name contain values for the last iteration of the loop.
Although you haven't tagged the question with jQuery, it does look like jQuery, so here's a solution:
I've taken the liberty to change $this to this because $this seems to be referring to the same object in each iteration, which is now what you may want (methinks)
var myArray = rows.map(function() {
return {
id: $(this).find('.elementOne').val(),
name: $(this).find('.elementTwo').text()
};
});
You can do it like this with jquery. The function will expect form elements of type input. It will iterate over thr passed form and it will collect each input name and value and it will create a json object like
Exmple:
HTML
<form action="" method="post" id="myForm">
<input type="text" name="field1" value="I am value of field 1"/>
<input type="text" name="field2" value="I am value of field 2"/>
</form>
Javascript
function buildObject(form) {
var jsonObject = [],
tempObj = {};
$(form).find("input:not(input[type='submit'])").each(function() {
tempObj[$(this).attr("name")] = $(this).val();
});
jsonObject.push(tempObj);
return jsonObject[0];
}
buildObject($("#myForm"));
//Will produce
jsonObj = {
field1 : "I am value of field 1",
field2 : "I am value of field 2"
}
This is because you're merely overwriting the same properties of your object, id and name, each time. You need to be making a sub-object for each, then push it into the master object (which I've converted to array, since it's non-associative).
var jsonObj = []
rows.each(function (index) {
var temp_obj = {};
temp_obj["id"] = $this.find('.elementOne').val();
temp_obj["name"] = $this.find('.elementTwo').text();
jsonObj.push(temp_obj);
});
[EDIT] - as Mark Eirich's answer shows, the temp_obj is unnecessary - you could push an anonymous object instead, but I defined temp_obj just to make it crystal clear what's happening.
Also read Quentin's very good points re: common confusion between JavaScript objects and JSON.
var jsonObj = [];
rows.each(function(index) {
jsonObj.push({
id: $this.find('.elementOne').val(),
name: $this.find('.elementTwo').text()
});
});

Categories