Javascript Array.push isn't working in get method - javascript

I am trying to implement a range property on a sequence object with the following code:
function RangeSeq(from, to) {
this.array = [];
this.from = from;
this.to = to;
this.arraySeq = new ArraySeq(this.range);
}
Object.defineProperty(RangeSeq.prototype, "range", {
get: function() {
for (var i = this.from; i <= this.to; i++) {
array.push[i];
console.log(this.array)
}
return array;
}
});
However, after running the code above, the array object still remains empty. Why is this so and what's the right way to solve this?

You used square brackets and not referring to this.array. It should be
this.array.push(i);

Related

JS multidimensional array spacefield

i wanna generate a 3x3 field. I want to do this with JS, it shall be a web application.
All fields shall inital with false. But it seems so that my code is not working correctly, but i don't find my fault. The goal is, that every spacesector is accessible.
Thats my idea:
// define size
var esize = generateSpace(3);
}
space[i] = false is replacing the array with a single boolean value false, not filling in all the entries in array you just created. You need another loop to initialize all the elements of the array.
function generateSpace(x) {
var space = [];
for (var i = 0; i < x; i++) {
space[i] = [];
for (var j = 0; j < x; j++) {
space[i][j] = false;
}
}
return space;
}
Also, your for() loop condition was wrong, as you weren't initializing the last element of space. It should have been i < space.length.
And when it's done, it needs to return the array that it created.
Since I got somewhat bored and felt like messing around, you can also initialize your dataset as shown below:
function generateSpace(x) {
return Array.apply(null, Array(x)).map(function() {
return Array.apply(null, Array(x)).map(function() {
return false;
});
});
}
The other functions work equally well, but here's a fairly simply looking one using ES6 that works for any square grid:
function generateSpace(x) {
return Array(x).fill(Array(x).fill(false));
}

Better solution to find a cell in an array

I have the following array:
var myArray = [
{
"id":1,
"name":"name1",
"resource_uri":"/api/v1/product/1"
},
{
"id":5,
"name":"name2",
"resource_uri":"/api/v1/product/5"
}
]
Each row is identified by it's unique id. I am quite new to Javascript and was wondering what was the best solution to find a cell based on id.
For example, for the id:5; my function must return:
findCell(myTable, id=5);
// this function must return:
{
"id":5,
"name":"name2",
"resource_uri":"/api/v1/product/5"
}
I'm quite afraid to do an ugly for loop... Maybe there is some built-in javascript function to perform such basic operations.
Thanks.
Yes there is a built-in function - filter. I would use it like this:
findCells(table, property, value) {
return table.filter(function (item) {
return item[property] === value;
});
}
findCells(myTable, "id", 5);
This is a bit modified version, of what you want: it can find all cells by the specified property name value.
Edit: using for loop to search the first occurence of the element is okay, actually:
findCell(table, id) {
var result = null;
for (var i = 0, cell = table[0], l = table.length; i < l; i++, cell = table[i]) {
if (cell.id === id) {
result = cell;
break;
}
}
return result;
}
findCell(myTable, 5);
Try this expression this might be helpful
var result = myArray.filter(function(element, index) { return element.ID == 5; });
filter() has two parameters
element - current row
index - current row index.
If you are going to stick with the array, the 'ugly' for loop is your best bet for compatibility. It's not that ugly when put in a function:
function findById(id) {
for(var i = 0; i < myArray.length; ++i) {
if(myArray[i].id === id) return myArray[i];
}
}
// Not checking return value here!
alert(findById(5).name);
Filter is another option if your concern is only with recent versions of browsers. It will return an array of values.
If your array is very large though, it would make sense to introduce some sort of index for efficient lookups. It adds an additional maintenance burden, but can increase performance for frequent lookups:
var index = {};
for(var i = 0; i < myArray.length; ++i) {
index[myArray[i].id] = i;
}
// Find element with id=5
alert(myArray[index[5]].name);
Example

Looping through an object with incremental property names

I'm trying to loop through an object like you would an array. I'm struggling to append the loop counter to the variable name.
I have an object like this (output with dump(), which I found here):
object(2): {
elem0: array(4): {
[0]: string(27): "http://placehold.it/300x300"
[1]: string(3): "0.8"
[2]: string(4): "-150"
[3]: string(3): "200"
}
elem1: array(4): {
[0]: string(27): "http://placehold.it/300x300"
[1]: string(3): "0.6"
[2]: string(3): "-70"
[3]: string(3): "458"
}
}
Here's how I'm trying to loop through it:
jQuery(document).ready(function($) {
// Provides object-measuring functionality
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
// Returns the number of objects in my object
var size = Object.size(window.depthElems);
/*
This is where I'm having difficulty.
I would like to use window.depthElems.elem0,
then window.depthElems.elem1, etc.
*/
for (var i = 0; i < size; i++) {
$('.wrapper').append('<img src="' + window.depthElems.elem+i+[0] + '" />');
}
});
I will, for the sake of argument, also provide my question as answer. You can use:
for(element in window.depthElems) {
if(window.depthElems.hasOwnProperty(element)) {
$('.wrapper').append('<img src="' + window.depthElems[element] + '" />');
}
}
This is not only more elegant, but also requires far less code. Of course if there is a reason to use the other code, please say so.
Note: This code is edited to also include the ability to read 'arrays', however the question was to make it work with 'objects'. If you use 'objects' the 'hasOwnProperty' check is superfluous.
Note #2: You can also use var hasOwn = Object.prototype.hasOwnProperty; like Azder said, which is a nice safeguard.
I apologize if my answer is over the top, I just like to prevent further hurt by miss-using JS (which I have experienced a lot) .
jQuery(document).ready(function($) {
var i; // there is no block scope in JS, so better to be clear and define i here
var $wrapper; // also
// Changing the JS built-in objects is problematic most of the time
// You should learn from jQuery and do wrapping instead
// Or at least just a good namespasing like:
// MyFramework.objectSize = function (obj) {}
Object.size = function(obj) {
var size = 0, key;
var hasOwn = Object.prototype.hasOwnProperty; // will explain further down
for (key in obj) {
// if obj has redifined hasOwnProperty = function(){ return false; }?
// it's better to use hasOwn like this if(hasOwn.call(obj,key)) {}
// and please do use braces even if only 1 statement
if(hasOwn.call(obj,key)) size++;
}
return size;
};
// Returns the number of objects in my JSON object
var size = Object.size(window.depthElems);
$wrapper = $('.wrapper'); // cached so jQuery doesn't search for it each iteration
// i is scoped to the whole function anyways
for (i = 0; i < size; i++) {
// $.each even guards you of the changing DOM which can cause
// infinite loops (you don't have that problem here, but... good to know
$.each(window['depthElems'+i],function(index,element){
$wrapper.append('<img src="' + element + '" />');
});
}
});
Also, since you already make objects named elem1, elem2, elem3,... you might as well use a two dimensional array, like window.depthElems = [[],[],[]]

Can't call public method while looping over object array

I'm starting to play around a bit with OOP in JavaScript and I have an array of simple objects that I'm trying to loop over and call a method on each, however, when I run this under Google Chrome, I get the following exception in the JavaScript debugger:
Uncaught TypeError: Object 0 has no method 'drawHisto'
Simplified code snippet below:
var histograms = [];
var h1 = null;
var h2 = null;
var h3 = null;
function Init() {
h1 = new Histogram(canvas1, "red");
h2 = new Histogram(canvas2, "blue");
h3 = new Histogram(canvas3, "green");
histograms = [ h1, h2, h3];
}
function Histogram(canvas, color) {
// this is my constructor
}
Histogram.prototype.drawHisto = function() {
// I will add code here to draw the histogram
}
function DrawHistograms() {
for (var h in histograms) {
h.drawHisto(); // Throws exception!
}
// h1.drawHisto() <--- this works
}
Any idea what I might be doing wrong? I've simplified the code here a bit, so if you find that the problem must be elsewhere, I can add additional context.
Thank you.
A for in loop in JavaScript does not iterate over an array's values, but rather over an object's keys. Simply use a for loop as usual:
function DrawHistograms() {
for (var i = 0; i < histograms.length; i++) {
histograms[i].drawHisto();
}
}
Or, if compatibility with Internet Explorer 8 and earlier is no issue, you may be able to use Array.forEach:
function DrawHistograms() {
histograms.forEach(function(h) {
h.drawHisto();
});
}
for (var h in histograms) {
histograms[h].drawHisto();
}
The for-in-loop in Javascript can be surprising at first: it doesn't loop over the values of the array, but rather the keys. For a straight-up array, I tend to prefer the more verbose but clearer standard for-loop:
for (var i = 0; i < histograms.length; i++) {
histograms[i].drawHisto();
}
Fun fact time! The for-in-loop can be handy for iterating over key-value mappings like {foo: 'bar', spam: 'eggs'}, but beware: it'll iterate over inherited keys, as well. For example, if some wiseguy decided to declare Object.prototype.myMethod, you'd see the keys foo, spam, and myMethod appear. The hasOwnProperty method can make the loop safe, though:
for (var key in obj) {
if(obj.hasOwnProperty(key)) {
// proceed with confidence
}
}

How to find index of object in a JavaScript array with jQuery

I am trying to find the index of an object in an array in jquery.
I cannot use jQuery.inArray because i want to match objects on a certain property.
I am using:
jQuery.inObjectArray = function(arr, func)
{
for(var i=0;i<arr.length;i++)
if(func(arr[i]))
return i;
return -1;
}
and then calling:
jQuery.inObjectArray([{Foo:"Bar"}], function(item){return item.Foo == "Bar"})
Is there a built in way?
Not sure why each() doesn't work for you:
BROKEN -- SEE FIX BELOW
function check(arr, closure)
{
$.each(arr,function(idx, val){
// Note, two options are presented below. You only need one.
// Return idx instead of val (in either case) if you want the index
// instead of the value.
// option 1. Just check it inline.
if (val['Foo'] == 'Bar') return val;
// option 2. Run the closure:
if (closure(val)) return val;
});
return -1;
}
Additional example for Op comments.
Array.prototype.UContains = function(closure)
{
var i, pLen = this.length;
for (i = 0; i < pLen; i++)
{
if (closure(this[i])) { return i; }
}
return -1;
}
// usage:
// var closure = function(itm) { return itm.Foo == 'bar'; };
// var index = [{'Foo':'Bar'}].UContains(closure);
Ok, my first example IS HORKED. Pointed out to me after some 6 months and multiple upvotes. : )
Properly, check() should look like this:
function check(arr, closure)
{
var retVal = false; // Set up return value.
$.each(arr,function(idx, val){
// Note, two options are presented below. You only need one.
// Return idx instead of val (in either case) if you want the index
// instead of the value.
// option 1. Just check it inline.
if (val['Foo'] == 'Bar') retVal = true; // Override parent scoped return value.
// option 2. Run the closure:
if (closure(val)) retVal = true;
});
return retVal;
}
The reason here is pretty simple... the scoping of the return was just wrong.
At least the prototype object version (the one I actually checked) worked.
Thanks Crashalot. My bad.

Categories