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)];
}
Related
I would like to write a function that will search the fields of objects in an array for a specific string, adding this object to a new array if the string is found in any of the object's fields. I've gotten my function to work, but was having the issue of the new list containing multiple copies of the objects which contain multiple copies of the string being searched for. I know this is because I've looped it so that each field it finds the string in, it will add the object once more to the new array. However, I wasn't sure of what alternative way I could go about writing the function to add the object only once, regardless of how many of its fields have matched with the string being searched for. This is my function:
function search (keyword, array){
var newArray = [];
for(let i = 0; i < array.length; i++) {
for (key in array[i]) {
if(array[i][key].includes(keyword)){
newArray.push(array[i]);
}
}
}
return newArray;
}
An example of where the output is problematic is if I do:
console.log(search('yes', myArray))
And if myArray contains an object in which 'yes' appears in 3 different fields, it will add this object to newArray 3 times.
Improved version of Danny Buonocore code.
No accidental global variables.
Uses forEach to iterate over the array.
Uses for...of and Object.values() to iterate over the values of the object (using for..in iterates over all non-Symbol, enumerable properties of an object itself and those the object inherits from its constructor's prototype and are cause for many bugs)
"short circuit" the test for adding an object: if a value has matched, there is no need to check the other values. This alone would probably solved your problem, but using a set will prevent duplicates if you have the same object multiple times in your array.
function search (keyword, array){
var result = new Set();
array.forEach( object => {
for (const value of Object.values(object)) {
if ( value.includes(keyword) ) {
result.add(object);
continue; // Don't need to check more on this item.
}
}
});
return Array.from(result);
}
console.log(search("yes", [
{ key1 :"yes", key2:"yes" },
{ key1 :"no", key2:"no" }
]));
You could use a Set, this will prevent duplicates.
function search (keyword, array){
var result = new Set();
for(let i = 0; i < array.length; i++) {
for (key in array[i]) {
if(array[i][key].includes(keyword)){
result.add(array[i]);
}
}
}
return Array.from(result);
}
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).
I understand the basic structure of a For loop in JavaScript. I was looking at the following example:
function howMany(selectObject) {
var numberSelected = 0;
for (var i = 0; i < selectObject.options.length; i++) {
if (selectObject.options[i].selected) {
numberSelected++;
}
}
return numberSelected;
}
On the Fourth line I don't understand what you would call the
[i] in terminology and why it is square brackets?
[] is a way of selecting a property from an object given a specific key, in this case the key (or index) is i and the object is an array. In an array an index can go from 0 to the length of the array - 1.
In an object a key is the name of any property within that object. For example, you can also select the value of the property key selected from the object selectObject.options[i] by using the following: selectedObject.options[i]['selected'].
As an alternative to your for loop, you could use a for in loop. Which works on objects (and arrays).
for (var key in selectObject.options) {
if (selectObject.options[key].selected) {
numberSelected++;
}
}
the [i] is used to address variables in for example an array.
Lets say you have an array names containing sarah and john. names[0] would return sarah.
What your for loop does is go over all the entries in selectObject.options and looks at the value of selected (most likely a true/false).
selectObject.options returns an array, and the [ ], is the way to get an element from the array, using its index (the i in your case)
Say you had an array of strings like so:
var arr = ["this", "is", "an", "array", "of", "strings"];
and you want to access one of the array's elements, you would:
console.log(arr[5]); // prints "strings" to the console
function howMany(selectObject) {
var numberSelected = 0;
for (var i = 0; i < selectObject.options.length; i++) {
if (selectObject.options[i].selected) {
numberSelected++;
}
}
return numberSelected;
}
In this above code why is numberSelected, and in the coditional statement numberSelected++
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.
Consider this Array
var LIST =[];
LIST['C']=[];
LIST['B']=[];
LIST['C']['cc']=[];
LIST['B']['bb']=[];
LIST['C']['cc'].push('cc0');
LIST['C']['cc'].push('cc1');
LIST['C']['cc'].push('cc2');
LIST['B']['bb'].push('bb0');
LIST['B']['bb'].push('bb1');
LIST['B']['bb'].push('bb2');
I can loop through this array like
for(var i in LIST){
console.log(i)//C,B
var level1=LIST[i];
for(var j in level1){
console.log(j)//cc,bb
// etc...
}
}
Fine.. I have few basic questions.
1.How to sort the array in each level?
One level can be sort by .sort(fn) method . How can i pass to inner levels?
2.Why the indexOf method does not works to find the elements in first two levels?
If it's because of the a non string parameter .. how can i search an array items in array if the item is not string?
3.How for(var i in LIST) works ?
I just need a basic understanding of indexing and looping through array ..
Thanks ..
LIST is NOT a three dimensional array in Javascript, it is just an array.
//declare an array which names LIST.
var LIST = [];
//set a property named 'C' of the LIST to be an array.
LIST['C']=[];
//set a property named 'B' of the LIST to be an array.
LIST['B']=[];
//set a property named 'cc' of the 'LIST.C'(which is an array object)
LIST['C']['cc']=[];
//set a property named 'bb' of the 'LIST.B'(which is an array object)
LIST['B']['bb']=[];
The fact is you only need to let the last level to be an array, see my example code below.
function iterateOrderd(obj) {
if (obj instanceof Array) {
obj.sort();
for (var j = 0, l=obj.length; j < l; j++) {
console.log(obj[j]);
}
} else {
var sortable = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
sortable.push(i);
}
}
sortable.sort();
for (var j = 0, l=sortable.length; j < l; j++) {
console.log(sortable[j]);
iterateOrderd(obj[sortable[j]]);
}
}
}
var LIST = {};
LIST['C'] = {};
LIST['B'] = {};
LIST['C']['cc']=[];
LIST['B']['bb']=[];
LIST['C']['cc'].push('cc0');
LIST['C']['cc'].push('cc1');
LIST['C']['cc'].push('cc2');
LIST['B']['bb'].push('bb0');
LIST['B']['bb'].push('bb1');
LIST['B']['bb'].push('bb2');
iterateOrderd(LIST);
You need to know that Array inherits from Object.
In JavaScript, any Object instance is an associative array(!), so acts like an Array in PHP. For example:
var o = {}; // or new Object();
o['foo'] = 'bar';
o[0] = 'baz';
for (i in o) { console.log(i, o[i]); }
Sorting an Object does not make much sense. indexOf would kinda work in theory, but is not implemented.
Arrays are ordered lists. Array instances have push(), length, indexOf(), sort() etc., but those only work for numerical indexes. But again, Array inherits from Object, so any array can also contain non-numerical index entries:
var a = []; // or new Array();
a[0] = 'foo'; // a.length is now 1
a.push('baz'); // a[1] === 'baz'
a.qux = 1; // will not affect a.length
a.sort(); // will not affect a.qux
for (i in a) { console.log(i, a[i]); }
I recommend playing around with arrays and objects, and you'll soon get the point.
What is your sorting criteria ? I mean how will you say array firstArray comes before secondArray?
regarding the for (counter in myArray), counter will take values of an array element in every iteration.
for (counter in [0,1,5]), counter will have values 0, 1 and 5 in the 3 iterations.
In your case, i will have values LIST['B'] and LIST['C'] in the two iterations and j will have values LIST['B']['bb'], LIST['B']['cc'], LIST['C']['bb'] and LIST['C']['cc'].
Both i and j will be arrays.