-1

Lets say I have this array

[{k:2, v:"Stack"}, {k:5, v:"Over"}, , {k:9, v:"flow"}]

How do I select elements like all keys with the value <=5? or the first 2 elements or all values when on odd numbered key (to spell Overflow)

I don't want to use a for/foreach loop. I'm looking for something like jquery where I can apply something to everything it matches. Kind of like how this applies newclassproperty to all a inside of a dom with the group class

$('.group a').addClass('newclassproperty')
BruteCode
  • 1,143
  • 7
  • 16
  • 22
  • 2
    Where is the question ? Where are the tries ? – soyuka Mar 14 '13 at 15:13
  • 1
    You're going to have to give a *very* good reason for not using a for loop, as that's all that most people will tell you to do always. I say this partly in jest, but partly sincerely...will a 'while' loop do? – Matt Taylor Mar 14 '13 at 15:13
  • Your requirements are very confusing .. keys with value <= 5 OR the first two elements OR all odd numbered keys ... which one is it? – Explosion Pills Mar 14 '13 at 15:14
  • You could use `.each()`, but it's essentially the same as a `foreach` loop. – Matt Burland Mar 14 '13 at 15:15
  • @ExplosionPills: Those are examples. I'm looking for something like linq in C# or jquery modifiying the dom (`$('.group a').addClass('newclassproperty')` – BruteCode Mar 14 '13 at 15:16
  • @soyuka: essentially I was looking for jLinq but thought jquery had the operations I wanted – BruteCode Mar 14 '13 at 15:52
  • @MattTaylor: Idk why people think I need a loop. It turns out jlinq is what i am looking for but I thought jquery had those ops (see edit for a example) – BruteCode Mar 14 '13 at 15:53

4 Answers4

5

Use array.filter, and the loop will be invisible to you:

lessThan5 = array.filter(function (elem) {
    return elem.k <= 5;
});
Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • beware IE < 9 but otherwise the solution of choice (although it is effectively a loop). – Christoph Mar 14 '13 at 15:17
  • 1
    @Christoph see the Compability section of the linked document – Explosion Pills Mar 14 '13 at 15:18
  • This is pretty close to what I want. I was looking for more of a lib so i can do a combo of things easier (like linq in .NET) – BruteCode Mar 14 '13 at 15:19
  • 1
    I know MDN very well, I just wanted to explicitely state it since many people have the habit to just copy teh codez and then whine when not wrkin at all. – Christoph Mar 14 '13 at 15:19
  • Also you might not be happy about [this question where the performance of Array.prototype.filter is discussed](http://stackoverflow.com/questions/14647470/performance-of-jquery-grep-vs-array-filter). To state it short - it sucks - it's **way** faster to go with a plain loop. – Christoph Mar 14 '13 at 15:22
  • @BruteCode: If you want an implicit iterator sort of *(but not quite)* like jQuery, use `.filter()` but create a series of function factories that fill your need. For example, you could have a factory that returns a function that compares a property value to a number. `array.filter(propLTE("k", 5))` So the `propLTE` would return a function that expects an object as the first argument, and would test if the property `"k"` is less than or equal to `5`. – the system Mar 14 '13 at 15:24
  • jLinq is what I was looking for. I just thought some similar operations were available in jquery – BruteCode Mar 14 '13 at 15:50
2

Depending on the browser support you need, you're probably looking for the JavaScript 1.6 Array.filter method.

var arr = [{k:2, v:"Stack"}, {k:5, v:"Over"}, , {k:9, v:"flow"}]
var odds = arr.filter(function(item, index) {
  return !(item.k % 2)
});
var small = arr.filter(function(item, index) {
  return item.k < 5
});
var first = arr.slice(0, 2);
Cecchi
  • 1,525
  • 9
  • 9
  • Pretty close to what I want although a bit verbose. I know I can combine this with map but selecting the data seems a bit of work tho. jLinq is what I was looking for. – BruteCode Mar 14 '13 at 15:51
  • Whatever floats your boat, but be aware that by definition any solution to this problem will involve a "loop". Just because the method is called `filter` or it is hidden in a different library doesn't mean the object isn't being traversed/looped at some level. If chaining is important to you, that is still possible with most of the built in Array methods, but - yes - a library like jLinq might keep things more readable for you. – Cecchi Mar 14 '13 at 18:44
1
$.each(result_data_array_from_json, function(key, value) {
      if(key <= 5){
             //your statements
      }
});
Vijay Verma
  • 3,660
  • 2
  • 19
  • 27
0

Due to performance reasons at the moment I would suggest to use a plain loop and encapsulate this into a custom function (e.g. by extending Array.prototype or using your own wrapper function) or use jQuery (=overkill) for such a task.

var t = [{k:2, v:"Stack"}, {k:5, v:"Over"}, , {k:9, v:"flow"}];
var r = [];

r = t.filter(function (elem) {
    return elem.k <= 5;
});

vs

for (var i = 0, l = t.length;i<=l;i++){
   if(t[i] && t[i].k <= 5){r.push(t[i])}
}

See the performance test on your specific case.

Community
  • 1
  • 1
Christoph
  • 50,121
  • 21
  • 99
  • 128