Daniel
Daniel

Reputation: 3691

How to send return statement to parent function?

Not sure how to explain this. I'll try it with an example.

For example, I use the following function as a short for a for loop over an array:

function forEach(array, f) {
  var len = array.length, i;
  for (i = 0; i < len; i += 1) {
    f(i, array[i], len);
  }
};

I guess this is not too uncommon. But it leads to problems when replacing the following for loop within a function:

function test(someArray) {
  for (var i = 0; i < someArray.length; i++) {
    if (someArray[i] === 23) {
      return true;
    }
  }
  return false;
}

The replacement:

function test(someArray) {
  forEach(someArray, function(i, value) {
    if (value === 23) {
      return true;
    }
  });
  return false;
}

Does not return the function test when 23 is reached and returns true but keeps executing the statements after the forEach and returns false.

Upvotes: 2

Views: 1757

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386624

First of all, please use for a callback the same style as in the API for array. Then use the callback as check and leave the decision to the calling function to use the information.

In this case the callback looks for a number and return true if the element is equal to 23. The calling function stops the iteration when receiving true and return true. Otherwise the iteration goes on and if not found, the return value is false.

function forEach(array, f) {
    var len = array.length,
        i;

    for (i = 0; i < len; i ++) {
        if (f(array[i], i, array)) {
            return true;
        }
    }
    return false;
}

var cb = function (v) { console.log('value', v); return v === 23; };

console.log('result', forEach([1, 2, 3, 4, 5, 23, 6, 7], cb));
console.log('result', forEach([1, 2, 3, 4, 5, 6, 7, 33], cb));
.as-console-wrapper { max-height: 100% !important; top: 0; }

For a different approach, like to get a value back, I suggest to return the item instead of a boolean value. If not found, return undefined.

function forEach(array, f) {
    var len = array.length,
        i;

    for (i = 0; i < len; i ++) {
        if (f(array[i], i, array)) {
            return array[i];
        }
    }
}

var cb = function (v) { console.log('value', v); return v === 23; };

console.log('result', forEach([1, 2, 3, 4, 5, 23, 6, 7], cb));
console.log('result', forEach([1, 2, 3, 4, 5, 6, 7, 33], cb));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

haffla
haffla

Reputation: 1066

Your forEach() function needs to return a value. Otherwise of course you will always return false after calling forEach().

function forEach(array, f) {
  var len = array.length, i;
  for (i = 0; i < len; i += 1) {
    if (f(i, array[i], len)) {
        return true;
    }
  }
  return false;
};

function test(someArray) {
  return forEach(someArray, function(i, value) {
    return value == 23;
  });
}

Upvotes: 1

salezica
salezica

Reputation: 76949

There are several ways of achieving the effect. This is a simple one:

function test(someArray) {
  var result = false

  forEach(someArray, function(i, value) {
    if (value == 23) result = true;
  });

  return result;
}

Note that value should be compared with ==. A single = is for assignment, it just replaces value.

The disadvantage of using forEach here is that the loop won't stop when value is 23. It will finish interating through all the items, even if 23 is the first on the list. With the for-return combo, iteration stops as soon as 23 is found.

If this worries you, there's a trick or two for stopping forEach, but the for-return approach is cleaner.

Upvotes: 0

Related Questions