简体   繁体   中英

JSON object -> array? how should I convert it?

Take two:) I have a jquery's autocomplete texbox and, upon a click of a button, I need to check if the value entered has come from the autocomplete or is it a completely new value.

The problems is that 'cache' is some sort of an array of JSON objects, but to be able to use if ( input in cache ) {... } I need to convert it to a simple javascript array. What would be the best way to do that?

PS FireBug says 'cache=[object Object]'

//////////////////////////////////////////// autocomplete code //////////////////
    var cache = {},
        lastXhr;
    $( "#inputV" ).autocomplete({
        minLength: 2,
        source: function( request, response ) {
            var term = request.term;
            if ( term in cache ) {
                response( cache[ term ] );
                return;
            }

            lastXhr = $.getJSON( "search.php", request, function( data, status, xhr ) {
                cache[ term ] = data;
                if ( xhr === lastXhr ) {
                    response( data );
                }
            });
        }
    });


////////////////////////// check if input comes from autocomplete  //////////////////
    $('#btn_check').click(function()        {

        var input = $("#inputV").val();
        alert(input);

        console.log('cache='+cache); 
        /// FireBug says 'cache=[object Object]'

        if ( input in cache ) 
            {
                alert("yes");
             }  
            else
            {
                alert("no");
            }   
    });

Here's that a response looks like.

[
    {
        "id": "Podiceps nigricollis",
        "label": "Black-necked Grebe",
        "value": "Black-necked Grebe"
    },
    {
        "id": "Nycticorax nycticorax",
        "label": "Black-crowned Night Heron",
        "value": "Black-crowned Night Heron"
    },
    {
        "id": "Tetrao tetrix",
        "label": "Black Grouse",
        "value": "Black Grouse"
    },
    {
        "id": "Limosa limosa",
        "label": "Black-tailed Godwit",
        "value": "Black-tailed Godwit"
    },
    {
            "id": "Chlidonias niger",
        "label": "Black Tern",
        "value": "Black Tern"
    },
    {
        "id": "Larus marinus",
        "label": "Great Black-backed Gull",
        "value": "Great Black-backed Gull"
    },
    {
        "id": "Larus fuscus",
        "label": "Lesser Black-backed Gull",
        "value": "Lesser Black-backed Gull"
    },
    {
        "id": "Larus ridibundus",
        "label": "Black-headed Gull",
        "value": "Black-headed Gull"
    },
    {
        "id": "Turdus merula",
        "label": "Common Blackbird",
        "value": "Common Blackbird"
    },
    {
        "id": "Sylvia atricapilla",
        "label": "Blackcap",
        "value": "Blackcap"
    },
    {
        "id": "Rissa tridactyla",
        "label": "Black-legged Kittiwake",
        "value": "Black-legged Kittiwake"
    },
    {
        "id": "Aegypius monachus",
        "label": "Eurasian Black Vulture",
        "value": "Eurasian Black Vulture"
    }
]

(Replacement answer, I hadn't meant the last one to be a CW.)

The problems is that 'cache' is some sort of an array of JSON objects

Actually, it's not an array. It's an object. (It's created via var cache = {}; , which is how we can tell.)

...but to be able to use if ( input in cache ) {... } I need to convert it to a simple javascript array.

Actually, no. The in operator in this context tests to see if an object contains a property with the name you give it. Example:

var obj = {foo: 1};  // An object with a property called "foo"
alert('foo' in obj); // alerts true, `obj` has a "foo" property
alert('bar' in obj); // alerts false, there is no "bar" property in `obj`

Note that the left-hand side of the in operator must be a string (it can be a literal, as above, or any expression that results in a string, such as a variable reference).

The code in your click handler is taking the value of the "inputV" field and seeing if that value is the name of a property in the cache object.

You probably want to check if it's the value of one of the properties of the cache object. If so:

$('#btn_check').click(function()        {

    var input = $("#inputV").val();
    var found, propName;

    alert(input);

    console.log('cache='+cache); 
    /// FireBug says 'cache=[object Object]'

    found = false;
    for (propName in cache ) {
        if (cache[propName] == input) {
            found = true;
            break;
        }
    }
    alert(found);
});

Since we know cache is a boring old object (from the fact it's created with var cache = {}; ), we can pretty safely use a raw for..in loop as above. But if you wanted to be more careful, you would use hasOwnProperty to make sure that you only checked propeties that cache has its own copy of (as opposed to ones it inherits from its prototype):

    for (propName in cache ) {
        if (cache.hasOwnProperty(propName) && cache[propName] == input) {
            found = true;
            break;
        }
    }

Again, though, it's not really necessary in this case, because we know that cache is a plain object, and barring someone doing something really silly like extending Object.prototype (which Thou Shalt Not Do), all of its enumerable properties (the things that for..in enumerates) are its own properties.

It's hard to tell without seeing what the JSON looks like. It's possible that you could substitute if ( input in cache ) with if(cache.hasOwnProperty(input)) and not bother converting it to an array, but it depends what the cache object contains.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM