2

Is there any not loop-based approach in JavaScript or JQuery that can check presence of some VALUE from object's properties. I mean here if I have

obj = { prop1:val, prop2:val2 }

is that possible with maybe one statement check is val2 presence among values of obj ?

UPDATE 1: The loop here is not the key! I can use loop if it is wrapped in some JQuery predefined function!

UPDATE 2: Writing a hand-made function is not so elegant, I think. I would like to find some library based solution for such a common and usual problem.

Michael Z
  • 3,883
  • 10
  • 43
  • 57
  • 2
    Short answer: no, you have to iterate over the object, or use a function that iterates over the object. – zzzzBov Nov 30 '12 at 18:06
  • Depends what you are trying to do. Are you trying to test for the presence of a known property of an object in another? – Mike Bonds Nov 30 '12 at 18:10
  • Yes, that exactly what I am trying to do! – Michael Z Nov 30 '12 at 18:12
  • @zzzzBov what function do you mean? Just written by myself with for-loop for testing value presence? I would like to have more elegant solution – Michael Z Nov 30 '12 at 18:14
  • 1
    @MichaelZ, you said "non loop-based approach" which is not possible as any function you might use to search would need to use a loop in one way or another. There are certainly elegant functions that exist so that you might call something along the lines of `contains(obj, val2)`, but in that case the `contains` function would be loop-based. – zzzzBov Nov 30 '12 at 18:19
  • ok, sorry, see mine clarifications at UPDATE – Michael Z Nov 30 '12 at 18:23
  • 1
    It should be noted that the "duplicate" referenced isn't a duplicate at all -- that one is asking to *search* the text in all keys, not match them. – McGarnagle Nov 30 '12 at 22:15

4 Answers4

4

No you cannot find if a value exist in an object in one statement without looping.

You can use native API or a library.. but they are going to internally loop thru all values.

The toll on any other method will be same as iterating the object.. So I would write a simple for loop to do it.

I would simply write this 4 line code in my script file and include that script file instead of including a library.. which would be the same. http://jsfiddle.net/sQW4P/2/ <-- Incase if you need such a function.

Selvakumar Arumugam
  • 79,297
  • 15
  • 120
  • 134
  • The loop here is not the key! I can use loop if it is wrapped in some JQuery predefined function! – Michael Z Nov 30 '12 at 18:15
  • @MichaelZ, then you need to clarify your question. – zzzzBov Nov 30 '12 at 18:20
  • @MichaelZ I don't think there is any such function in jQuery. So if you worried about having the loop inside your webpage.. move it to script file, name it a function and call the function. I think it should be available in some other library.. but adding a new library for this is no good. – Selvakumar Arumugam Nov 30 '12 at 18:20
  • Writing a hand-made function is not so elegant, I think. I would like to find some library based solution for such a common and usual problem. – Michael Z Nov 30 '12 at 18:26
  • @MichaelZ In my opinion, writing hand-made 1000 line code is not so elegant.. but looking for a library to write a 4 line code is not my style. http://jsfiddle.net/sQW4P/2/ – Selvakumar Arumugam Nov 30 '12 at 18:32
1

This works with jQuery:

$.grep($.map(obj, function(v,k){return v}), function(el){return el == val2})

You could wrap it like so:

function hasVal(o, v) {
  $.grep($.map(o, function(v,k){return v}), function(el){return el == v}).length > 0
}
Faiz
  • 16,025
  • 5
  • 48
  • 37
1

If you're ok using an external library, Underscore.js is fairly concise:

_.contains(_.values(obj), "val2");
// true

This is Underscore's values method:

Return all of the values of the object's properties.

Here is its implementation from the source code:

// Retrieve the values of an object's properties.
  _.values = function(obj) {
    var values = [];
    for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
    return values;
  };

As you can see, it just iterates over the keys in the object, and pushes them to an array. So, no, it's not possible to do this without an iteration.

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
0

The only way I can think of is JSON:

new RegExp(':\"'+val+'\"').test(JSON.stringify(obj))

Demo: http://jsfiddle.net/J4TDS/

If you are fine with using a function, no need to look in libs, it’s only a few bytes:

function find(o, v) {
    for(var i in o) {
        if (o[i] === v) return true;
    }
}

find(obj, val2);
David Hellsing
  • 106,495
  • 44
  • 176
  • 212
  • Doesn't this hide some loops inside the RegExp? – Almo Nov 30 '12 at 18:14
  • @David, a regex has a loop to scan through the string. AND, JSON.stringify loops through the object to build the string. This has multiple loops. – jfriend00 Nov 30 '12 at 18:17
  • @David Hmmm, you have a nice solution. It doesn't matter for me if it inner implementation has loops! – Michael Z Nov 30 '12 at 18:20
  • @MichaelZ if you are fine with writing a function that loops, then you should do that instead. Using JSON comparison like this is not very safe – David Hellsing Nov 30 '12 at 18:21
  • @MichaelZ If you worried about having the loop inside in your webpage.. then move that code to script file, name it a function and call the function which is same as including a library and calling its function. – Selvakumar Arumugam Nov 30 '12 at 18:22
  • Writing a hand-made function is not so elegant, I think. I would like to find some library based solution for such a common and usual problem. – Michael Z Nov 30 '12 at 18:22