Why my extend function is not working? - javascript

extend is based on each function:
function each(collection,iterator) {
if (Array.isArray(collection)) {
for (var i=0; i < collection.length; i++) {
iterator(collection[i]);
}
} else {
for (var key in collection) {
iterator(collection[key]);
}
}
}
after I check underscore.js, apparently the extend function takes two parameters...but im not sure how to rewrite the function so it can work?
function extend(newProperty) {
each(arguments,function(source) {
each(source,function(value,key) {
newProperty[key]=value;
})
})
return newProperty;
}
var iceCream = {flavor: "chocolate"};
extend(iceCream,{sprinkles: "lots"});
//==> { flavor: 'chocolate', undefined: 'chocolate' }

Your each function is only providing the element of the collection, it should also provide the key. Try this.
function each(collection,iterator) {
if (Array.isArray(collection)) {
for (var i=0; i < collection.length; i++) {
iterator(collection[i], i);
}
} else {
for (var key in collection) {
iterator(collection[key], key);
}
}
}

Related

Clear an array with empty elements

I wrote the object as the second element in the array, and then sorted it. As a result, we got an array of one object and two empty values, which are not indicated in any way.
It looks like this: [{...}, empty × 2]
How can I clean it?
My code
for (i = 0; i < data.Levels.length; i++) {
$.each(data.Ranges, function() {
for (var property in this) {
if (this[property][i] != 0) {
isNullable = false;
break;
}
}
if (!isNullable) {
return false;
}
});
if (!isNullable) {
levels[i] = { //Writing object
Level: data.Levels[i],
Position: i
};
}
}
levels.sort(function (a, b) {
if (a.Level < b.Level) {
return -1;
}
if (a.Level > b.Level) {
return 1;
}
return 0;
});
Add new elements to the end of the array with push, avoiding creating a sparse array entirely:
for (i = 0; i < data.Levels.length; i++) {
$.each(data.Ranges, function() {
for (var property in this) {
if (this[property][i] != 0) {
isNullable = false;
break;
}
}
if (!isNullable) {
return false;
}
});
if (!isNullable) {
levels.push({ //Writing object
Level: data.Levels[i],
Position: i
});
}
}

Flatten Nested Array Without Using Flatten Function

I'm currently stuck on a problem. I'm trying to make [[1,2,[3]],4] -> [1,2,3,4] but cannot get it to work. The output I keep getting is: 1,2,3,4
1,2,3
3
3
3
3..........3
function flattenArray(input) {
var result = [];
console.log(input.toString());
for(i = 0; i < input.length; i++) {
if(input[i].constructor === Array) {
result.push(flattenArray(input[i]));
} else {
result.push(input[i]);
}
}
return result;
}
console.log(flattenArray([[1,2,[3]],4]));
I have this in my common.js file. I use it all the time.
Array.prototype.flatten = function () {
var ret = [];
for (var i = 0; i < this.length; i++) {
if (Array.isArray(this[i])) {
ret = ret.concat(this[i].flatten());
} else {
ret.push(this[i]);
}
}
return ret;
};
Here it is as a function:
function flattenArray(input) {
console.log(input.toString());
var ret = [];
for (var i = 0; i < input.length; i++) {
if (Array.isArray(input[i])) {
ret = ret.concat(flattenArray(input[i]));
} else {
ret.push(input[i]);
}
}
return ret;
}

Call nested function with if statement in Javascript

I am try to call a nesting function like below:
function public(val) {
if (val == "exist") {
function runList() {
for (var i = 0; i < arguments.length; i++) {
arguments[i]();
}
}
}
public.runList = runList;
}
var publicExist = "exist";
function test() {
console.log(test)
}
function testE() {
console.log(testE)
}
public(publicExist);
public.runList(test, testE);
I want to fire function, but these codes only show the text, how can I do?
You forgot to put quotes around 'test' and 'testE', which I am assuming you wanted to log to the console as strings.
function public(val) {
if (val == "exist") {
function runList() {
for (var i = 0; i < arguments.length; i++) {
arguments[i]();
}
}
}
public.runList = runList;
}
var publicExist = "exist";
function test() {
console.log('test')
}
function testE() {
console.log('testE')
}
public(publicExist);
public.runList(test, testE);
Just add quotes in test and testE method's console -
function public(val) {
if (val == "exist") {
function runList() {
for (var i = 0; i < arguments.length; i++) {
arguments[i]();
}
}
}
public.runList = runList;
}
var publicExist = "exist";
function test(){
console.log('test')
}
function testE(){
console.log('testE')
}
public(publicExist);
public.runList(test,testE);

javascript callbacks in for loop

I have a for loop in a function in the structure
func(var, callback) {
for(i = 0; i < len; i++) {
validate(var, function(value) {
if (!value) { callback(value) }
}
}
callback(true);
}
Where the function validate returns a boolean. I would only like to call my callback with true if it has not been called before. I tried putting a return after callback(value) but that didn't help.
Set a flag:
function func(foo, callback) {
var called = false;
for(var i = 0; i < len; i++) {
validate(foo, function(value) {
if (!value) {
called = true;
callback(value);
}
})
}
if (!called) {
callback(true);
}
}

JavaScript not returning int ..at least not when I think it should be

Assuming that arr is an array of objects.
arr = // some items;
function findItem( source, item ) {
return source.indexOf(item);
}
Now, I know the code is correct, it actually does find the right index, but I get an 'undefined' response. However if I do this..
function findItem( source, item ) {
var i = 0;
i = source.indexOf(item);
return i;
}
I get the right index.
I've even tried.
function findItem(source, item) {
return parseInt( source.indexOf(item) );
}
and I still get an 'undefined'.
Can someone tell me what in the world is going on?
Okay, to make things a bit simpler, I'll post more code here.
function init() {
alert(discoverWithoutVar());
alert(discoverWithVar());
}
function discoverWithoutVar() {
var arr = [{ Name: "Stacey" }, { Name: "Ciel" }, { Name: "Derek" }, { Name: "Christi"}];
// find the index of 'Ciel'
arrayForEach(arr, function (e) {
if (e.Name == "Ciel") {
return arrayIndexOf(arr, e);
}
});
}
function discoverWithVar() {
var arr = [{ Name: "Stacey" }, { Name: "Ciel" }, { Name: "Derek" }, { Name: "Christi"}];
var i = 0;
// find the index of 'Ciel'
arrayForEach(arr, function (e) {
if (e.Name == "Ciel") {
i = arrayIndexOf(arr, e);
}
});
return i;
}
function arrayForEach(array, action) {
for (var i = 0, j = array.length; i < j; i++)
action(array[i]);
}
function arrayIndexOf(array, item) {
if (typeof array.indexOf == "function")
return array.indexOf(item);
for (var i = 0, j = array.length; i < j; i++)
if (array[i] == item)
return i;
return -1;
}
Just to prove I wasn't lying about it working, a screenshot of the debugger.
I would advise you take a very close look at what you are passing for your variables.
Like Matthew said, you discard the value. Adding a return on arrayForEach would return the value found by your functions.
This is why you should post real code you've tested with. If you want to simplify, make it is as simple as you can while still showing the problem. Then post that.
function discoverWithoutVar() {
var arr = [{ Name: "Stacey" }, { Name: "Ciel" }, { Name: "Derek" }, { Name: "Christi"}];
// find the index of 'Ciel'
arrayForEach(arr, function (e) {
if (e.Name == "Ciel") {
return arrayIndexOf(arr, e);
}
});
}
is wrong, because you're just returning from the anonymous function you pass to the for each (not from discoverWithoutVar).
function arrayForEach(array, action) {
for (var i = 0, j = array.length; i < j; i++)
action(array[i]); // The value you return is being discarded here
}
Just use a regular for loop:
for(var i = 0; i < arr.length; i++)
{
if (arr[i].Name == "Ciel") {
return arrayIndexOf(arr, e);
}
}
The reason the var i makes it work is that i is being closed into the anonymous function. Then, you're setting it inside, but returning from the outer function. If the var i, i =, and return were all in the anonymous function, it would indeed make no difference.

Categories

Resources