I have a class like below;
function Request()
{
this.CompanyId;
this.Password;
this.SessionId;
this.UserId;
this.UserName;
}
I create an object and want to get byte array of object;
var request = new Request();
request.UserName = GlobalProcess.SessionInfo.Server.UserName;
request.Password = GlobalProcess.SessionInfo.Server.Password;
request.CompanyId = GlobalProcess.SessionInfo.SelectedDatabase.CompanyId.toString();
request.UserId = GlobalProcess.SessionInfo.UserId.toString();
request.SessionId = GlobalProcess.SessionInfo.SessionId.toString();
var requestbinary = GetByte(request);
console.log(requestbinary);
My GetByte function is;
function GetByteArrayFromStringArray(parameter)
{
var mainbytesArray = [];
for (var i = 0; i < parameter.length; i++)
mainbytesArray.push(parameter.charCodeAt(i));
return mainbytesArray;
}
In console, I get empty array. What am I doing wrong?
Try this
function GetByteArrayFromStringArray(parameter) {
for (var key in parameter) { // loop through properties
var mainbytesArray = [];
for (var i = 0; i < parameter[key].length; i++)
mainbytesArray.push(parameter[key].charCodeAt(i));
}
return mainbytesArray;
}
It loops through the properties and gets you the array of theese
You're passing an object to a function that expects a string (I think). Your object has no "length" property, so the loop does nothing at all.
You could have the function iterate through the object's properties, I suppose, and accumulate an array from the values of each one. That would not be terribly useful, I don't think, as in JavaScript you're not guaranteed that you'll iterate through an object's properties in any particular order.
Related
I have three arrays filled with objects in JavaScript that I've put into a multi-dimensional array in order to get all possible combinations of all three objects to create a set of 'rules'. Then later in the code I want to be able to pull out the properties of these objects, but when I attempt to all I seem to be able to get is the string "[object]" and not the actual object itself.
This is how the array is put together:
var allArrays = [settings.serviceLevels, settings.serviceDays, settings.services];
function allPossibleCases(arr) {
if (arr.length === 1) {
return arr[0];
} else {
var result = [];
var allCasesOfRest = allPossibleCases(arr.slice(1));
for (var i = 0; i < allCasesOfRest.length; i++) {
for (var j = 0; j < arr[0].length; j++) {
result.push(arr[0][j] + allCasesOfRest[i]);
}
}
return result;
}
}
var uncheckedRules = allPossibleCases(allArrays);
I need to be able to get the properties out of settings.serviceLevels, settings.serviceDays and settings.services - I can find questions that do this with regular arrays but not with objects - is this even possible or have I taken it to a level where I've lost the properties?
Not sure I understood what you wanted. But here's a recursive function that will store in an array the properties of objects contained in another array :
function listProps(object, result) {
// for each property of the object :
for (objectProperty in object) {
// if it's an object, recursive call :
if (typeof object[objectProperty] === 'object') {
listProps(object[objectProperty], result);
} else { // otherwise, push it into the result array :
result.push(object[objectProperty]);
}
}
}
var allArrays = [settings.serviceLevels, settings.serviceDays, settings.services];
var result = [];
listProps(allArrays, result);
The result array should list every properties from the three objects settings.serviceLevels, settings.serviceDays, settings.services and their children (if they contain any object themselves).
function removeDupes() {
var out = [],
obj = {};
for (x = 0; x < intArray.length; x++) {
obj[intArray[x]] = 1;
}
for (x in obj) {
out.push(x);
}
return out;
}
hi all, obj { } is supposed to have been declared as an object, but why putting [ ] and using obj as array works? thanks
someObject["somePropertyName"] is how you access the property of an object. (You can also use someObject.somePropertyName but only if the property name is a valid identifier).
The syntax has nothing specifically to do with arrays.
Arrays are just a type of object with a bunch of methods that treat property names that are integer numbers in special ways.
(Numbers are not valid identifiers so you must use the square bracket syntax to access properties with names that are numbers).
First of all, let's fix your removedDupes function by adding intArray as an argument and declaring the loop iterators as local variables var x:
function removeDupes(intArray) {
var out = [],
obj = {};
for (var x = 0; x < intArray.length; x++) {
obj[intArray[x]] = 1;
}
for (var x in obj) {
out.push(x);
}
return out;
}
The first loop iterates over all intArray elements. For each element it creates a new property on obj with key intArray[x] and value 1 via obj[intArray[x]] = 1. This is called bracket notation. Now, objects can't have duplicate keys. So adding the same property key twice actually overrides the previously added property. Thus, when the loop completes, your obj has exactly one key per unique array element.
The second loop then pushes these keys into the resulting out array.
There are some issues with your removeDupes function. Firstly, it returns an array of string elements even though the input is an array of number elements. This is because obj keys can't be numbers and are always converted to strings. You can fix it by storing the numeric values along with the keys as follows:
function removeDupes(intArray) {
var out = [],
obj = {};
for (var x = 0; x < intArray.length; x++) {
obj[intArray[x]] = intArray[x];
}
for (var x in obj) {
out.push(obj[x]);
}
return out;
}
Now, this works, but it is very verbose. You can make it shorter by replacing the second loop with return Object.values(obj);. Or even shorter by using a Set:
function removeDupes(intArray) {
return [...new Set(intArray)];
}
I have the following:
var params = {status: [69,71]};
var getTasks = function(params) {
if (params.status.constructor === Array) {
var statuses = params.status;
var newParams = [];
for (var i = 0; i < statuses.length; i++) {
params.status = statuses[i];
newParams.push(params);
}
console.log(newParams);
}
// else {
// ...
// }
};
Calling getTasks(params) logs newParams as:
[ { status: 71 }, { status: 71 } ].
I would expect this to log out
[ { status: 69 }, { status: 71 } ].
What am I missing here?
You're pushing the same Object twice, the most recent change to the Object is visible.
var obj;
for (var i = 0; i < statuses.length; i++) {
// construct obj as desired
obj = {}; // notice this new object is created inside the loop
obj.status = statuses[i];
// push to your array
newParams.push(obj);
}
newParams.push(params); is pushing the object referenced by params to your array. You have an array full of references to the same object, any modifications to that object will be present in each of the array elements, since they are all the same object. Create a new object each time instead of reusing the same one:
for (var i = 0; i < statuses.length; i++) {
newParams.push( { status: statuses[i] } );
}
params is a single object. Inside of your for loop, by doing the following:
for (var i = 0; i < statuses.length; i++) {
params.status = statuses[i];
newParams.push(params);
}
... you are overwriting the status field and pushing the object into the newParams array. However, the object isn't copied - instead, a reference to it is appended to the array. Thus, all elements of newParams are actually the same element.
Essentially, you need to push a clone of the params object into the array in the loop. If you're using jQuery or underscore, an easy way to clone is using the extend() function:
// jQuery
newParams.push(jQuery.extend({}, params));
// or Underscore
newParams.push(_.extend({}, params));
#PaulPro and #PaulS gave correct answers, but there's always an opportunity to learn something new. In this case, I'd recommend to take a look at Array.map which can greatly simplify your code:
function statutify(value) {
return { status: value };
}
var getTasks = function(params) {
if (params.status.constructor === Array) {
var newParams = params.status.map(statutify);
console.log(newParams);
}
// ...
};
Or, it can't hurt to learn something about other libraries like #voithos suggests.
I have rootObject which holds childObject as a value. I use two for loops to get values from childObject and put them to array. Array is cleared in every iteration of outer loop.
var childObject = new Object();
for (var i = 0; i < 3; ++i) {
childObject[i] = i*i;
}
var rootObject = new Object();
rootObject[0] = childObject;
I am using console.log(resultArray) to observe array. And this is what I got:
When clearing before second for loop
var resultArray = []
for ( var rootKey in rootObject){
resultArray.length = 0; //clearing array
for ( var childKey in rootObject[rootKey]){
resultArray.push([ parseInt(childKey), rootObject[rootKey][childKey] ]);
}
console.log(resultArray);
}
I get [Array[2], Array[2], Array[2]
When clearing after second for loop
var resultArray = []
for ( var rootKey in rootObject){
for ( var childKey in rootObject[rootKey]){
resultArray.push([ parseInt(childKey), rootObject[rootKey][childKey] ]);
}
console.log(resultArray);
resultArray.length = 0; //clearing array
}
I get []
Why result is different?
EDIT
I am using Firefox 29
http://jsfiddle.net/xf78k/5/ <-- good
http://jsfiddle.net/xf78k/6/ <-- bad
You store a reference to the array into your var, and print it through the console, that will show you the realtime (dynamic) state of the array.
In other words, the console will show you three times the same objects, in both cases, and its state will be the final state of resultArray.
If you converted it to string, or printed its length, you'd have the expected result, because it would be a primitive value, and the console wouldn't keep track of its reference.
Taste the difference:
var childObject = new Object();
for (var i = 0; i < 3; ++i) {
childObject[i] = i*i;
}
var rootObject = new Object();
rootObject[0] = childObject;
var resultArray = []
for ( var rootKey in rootObject){
for ( var childKey in rootObject[rootKey]){
resultArray.push([ parseInt(childKey), rootObject[rootKey][childKey] ]);
}
console.log(resultArray.length);
resultArray.length = 0; //clearing array
}
One suggestion: don't initialize plain objects with "new Object()".
var childObject = {};
is to be preferred instead.
EDIT: why you'd rather prefer the literal syntax to init objects
Try this code:
var a = new Object(1);
var b = new Object("1");
The result is that a is a Number(), and b is a String, because Object accept an optional parameter that drives which constructor is used for the object.
So, it is error prone.
Now try this:
Object = function () {
//xmlhttp=new XMLHttpRequest("malicious site"); ...
console.log("XSS attack")
}
var c = new Object();
any script can override it, while {} is safer.
Finally, due to JS engines optimization, the literal syntax leads to better performance.
More
console.log does lazy and async evaluation of variables. Since arrays are passed by reference, it's not strange for it to reflex the value it has after clearance.
If you insert a breakpoint before clearing you should see the array with its elements.
Suppose I have a global object that looks like this:
var TheFruits = {
323: {},
463: {},
223: {} ..... // can be thousands of properties
}
Basically, the keys are IDs and the values are themselves objects. Now suppose I have an array of IDs that I pass into a function and I want that function to return an array of references to the values that match the IDs of the global object (ie. no deep copy). Something like this:
function GetReferences(TheArrayOfIDs) {
var TheArrayOfReferences = [];
return TheArrayOfReferences;
}
Now I know I can write a for loop that iterates over TheArrayOfIDs and that then loops over the object keys at each iteration but then that's a loop within a loop. So I'm looking for the fastest way of doing it, and jquery is available.
Basically, if TheArrayOfIDs = [323, 463, 223]; then TheArrayOfReferences =[TheFruit.323, TheFruit.463, TheFruit.223];
Thanks.
You don't need a second loop:
var results = [];
for (var i = 0; i < ids.length; i++)
results.push(fruits[ids[i]]);
You have to do only one loop as key look-up is built-in :
var TheArrayOfReferences = TheArrayOfIDs.map(function(id){return TheFruits[id]});
Something like that should work :
var i = 0, l = TheArrayOfIDs.length;
for (i = 0; i < l; i++)
TheArrayOfReferences.push(TheFruits[TheArrayOfIDs[i]]);