Domanda

Was looking for "equivalent for some method in javascript" and "return just one value if is in array", but saw only the answers to the way in which to determine the type of variables or too many unnecessary.

I bypass all inputs in html and i want something like this:

$('#goodsFilter')
    .find('input[type="number"]')
    .some(function(i,el){
        return (isNumber($(el).val())) ? 1 : 0;
});

But it throws an error:

"TypeError: 'undefined' is not a function" (eg. Safari 6.0.4).


UPD: Error comes from the last line, yeah, where });. isNumber:

function isNumber(n) { return !isNaN(parseFloat(n)) && isFinite(n); }

This should check for the presence of each input information, and, if at least one of them is not empty, return 1, otherwise 0. How can I replace it to work in most modern browsers?

UPD: Problem was solved. I'm a little confused in choosing the answer. The code of @RobG implementation of .some() is more understandable for beginners (and I am) so I switched my vote.

È stato utile?

Soluzione 2

Array.prototype.some returns true or false, so you can do:

.some(function(el){
        return !isNaN(el.value);
}

You don't say where the error comes from, is it from the call to isNumber?

Edit

Ah, so your issue is with some.

If you want a jQuery some method, then it should at least mimic the built–in ECMAScript some, which takes two arguments: a callback function and an optional this argument.

The callback function should take three arguments: the value, the index (optional) and an optional value to use as the this argument. It should access the numeric members in ascending order and only visit members that actually exist.

So it should be something like (noting that jQuery.fn === jQuery.prototype):

jQuery.fn.some = function(fn, thisArg) {
  var result;

  for (var i=0, iLen = this.length; i<iLen; i++) {

    if (this.hasOwnProperty(i)) {

      if (typeof thisArg == 'undefined') {
        result = fn(this[i], i, this);

      } else {
        result = fn.call(thisArg, this[i], i, this);
      }

      if (result) return true;
    }  
  }
  return false;
}

So if you want now you can do:

var result = $('#goodsFilter')
              .find('input[type="number"]')
              .some(function(el) {
                 return isNumber(el.value); 
              })? 1 : 0; 

or you can do either of the following to coerce true to 1 and false to 0:

var result = Number($('#goodsFilter')
              .find('input[type="number"]')
              .some(function(el) {
                 return isNumber(el.value); 
              }));

or

var result = +($('#goodsFilter')
              .find('input[type="number"]')
              .some(function(el) {
                 return isNumber(el.value); 
              }));

The above is only lightly tested, the optional thisArg parameter might be redundant.

Altri suggerimenti

For anyone else who comes to this thread, you can use some() on a jQuery object this way:

 $.makeArray($(...)).some(function(x) { ... })

jQuery.makeArray() converts the jQuery object into an Array, so you can use some() on it.


As suggested by @alf-eaton, you could use:

$(…).toArray().some(function(node) { … })

$(...).is(function) should work too. The jQuery API documentation states (emphasis mine):

Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments.

So using the example in the question, we would have something like:

var result = $('#goodsFilter')
              .find('input[type="number"]')
              .is(function(idx, el) {
                  return isNumber(el.value); 
              })? 1 : 0; 

You could use the .filter method, and then check the length.

$('#goodsFilter')
    .find('input[type="number"]')
    .filter(function(i,el){ return isNumber($(el).val())); })
    .length > 0

. . In the most basic version, you can just create a "some" function:

function eSome(arr, f) { var i = 0, n = arr.length;
  for (;i<n;i++) { if (!i in arr) { continue }
    if (f(i, arr[i])) { return true; }
  } return false;
}

var list = [0, 1, 2, 3, 4, 5];
var testFunction = function (i, e) { return e === 2; };
console.log(eSome(list, testFunction));
//returns true and the loop ran only for the necessary three times.

. . If you want to chain the .some call in a jQuery object, you can add it as a jQuery function as well, using something like this (now tested and fixed) example:

jQuery.fn.some = function (f) { var i = 0, n = this.length;
  for (;i<n;i++) { if (!i in this) { continue }
    if (f(i, this[i])) { return true; }
  }
  return false;
}

$('.a').some(function (i, el) { return ($(el).text() == 'weeee!'); });

. . As @RobG pointed out in the comments, the native Array.prototype.some implementation calls your callback with a different set of parameters. I'm following the OP's sample code, but you can mimic the ECMA implementation's parameter with if (f(this[i], i, this)) { return true; } inside the loop.

. . You can also shim it on Array.prototype.some, but I strongly advise against any direct modifications to the built-in prototypes.

Implementation in Vanilla Javascript( with arrow syntax)

function some(arr,callback){
  for(let i=0;i<arr.length;i++){
    if(callback(arr[i],i,arr)){
      return true;
    }
  }
  return false;
}

some use:

check if an array has an even number:

function hasEvenNum(arr){
  return arr.some(value=>{
    return value % 2 === 0;
  });
}

Try to use [].prototype.call method, the first argument will be an Array-like value, the second one is a function that will be called on each element.

[].some.call($('#goodsFilter').find('input[type="number"]'), function (el) {
    return isNumber($(el).val());
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top