javascriptjqueryobject-properties

Object properties dynamic delete


I am curious about an improved way to dynamically delete properties from a javascript object based on wildcards. Firstly, suppose I have the following object:

object =
{
    checkbox_description_1 : 'Chatoyant',
    checkbox_description_2 : 'Desultory',
    random_property : 'Firefly is a great program',
    checkbox_mood_1 : 'Efflorescent',
    checkbox_description_3 : 'Ephemeral'
}

Task

Now, the end result is to have removed all properties under the guise of 'checkbox_description' and leave the rest of the object intact as shown:

object =
{
    random_property : 'Firefly is a great program',
    checkbox_mood_1 : 'Efflorescent',
}

My solution

At present my solution involves jquery and the following code:

var strKeyToDelete = 'checkbox_description'

/* Start looping through the object */
$.each(object, function(strKey, strValue) {

    /* Check if the key starts with the wildcard key to delete */
    if(this.match("^"+strKey) == strKeyToDelete) {

        /* Kill... */
        delete object[strKey];
    };
});

Issue

Something about this seems very inelegant to me and if the object were to be of reasonable size very process intensive. Is there a better way of performing this operation?


Solution

  • This is the bare minimum required:

    function deleteFromObject(keyPart, obj){
        for (var k in obj){          // Loop through the object
            if(~k.indexOf(keyPart)){ // If the current key contains the string we're looking for
                delete obj[k];       // Delete obj[key];
            }
        }
    }
    
    var myObject = {
        checkbox_description_1 : 'Chatoyant',
        checkbox_description_2 : 'Desultory',
        random_property : 'Firefly is a great program',
        checkbox_mood_1 : 'Efflorescent',
        checkbox_description_3 : 'Ephemeral'
    };
    deleteFromObject('checkbox_description', myObject);
    console.log(myObject);
    // myObject is now: {random_property: "Firefly is a great program", checkbox_mood_1: "Efflorescent"};
    

    So that's pretty close to the jQuery function you have.
    (Though a little faster, considering it doesn't use jQuery, and indexOf instead of match)

    So, what's with the ~ before indexOf?

    indexOf returns a integer value: -1 if the string is not found, and a index, starting from 0, if it is found. (So always a positive integer if found)
    ~ is a bitwise NOT, that inverts this output. As it happens to be, the inverted output of indexOf is just what we need to indicate "found" or "not found".

    ~-1 becomes 0, a false-ish value.
    ~x, where x is 0 or postitive, becomes -(x+1), a true-ish value.

    This way, ~string.indexOf('needle') acts like string.contains('needle'), a function that we don't have in JavaScript.

    Additionally, you could add a double boolean not (!!) in front of the ~, to convert the true-ish or false-ish output to a real true / false, but that's not necessary in JavaScript.
    Functionally, ~string.indexOf('needle') and !!~string.indexOf('needle') are equal.


    In case you specifically need the key to begin with the needle, replace the:

    ~k.indexOf(keyPart)
    

    With:

    k.indexOf(keyPart) === 0