715

Suppose I have this code:

var myArray = new Object();
myArray["firstname"] = "Bob";
myArray["lastname"] = "Smith";
myArray["age"] = 25;

Now if I wanted to remove "lastname"?....is there some equivalent of myArray["lastname"].remove()?

(I need the element gone because the number of elements is important and I want to keep things clean.)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 33
    A tip: don't get arrays and maps confused. Some languages, like php, have a single object for both. Though you used the right type here (new Object()) you named it myArray, it's just a matter of standards for a langugage. – Ruan Mendes Apr 27 '10 at 17:35
  • Don't forget that JavaScript is type-less and everything is an object. See Saul's answer below. – Stephan Kristyn Jun 15 '12 at 09:24
  • 4
    @StephanKristyn - to be precise, JS has types but in a [dynamic](http://en.wikipedia.org/wiki/Type_system#Dynamic_typing) and [weak](http://en.wikipedia.org/wiki/Type_system#Strong_and_weak_typing) way. For example, while its variables indeed are typeless, their values are not. That is the **dynamic** part. **Weak** denotes that [operations](https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Expressions_and_Operators) between different value types are not strictly defined and rely on behind-the-scenes conversions; for example `"Test" + {};` is a perfectly valid JS statement. – Saul Aug 27 '12 at 08:46

18 Answers18

1268

Objects in JavaScript can be thought of as associative arrays, mapping keys (properties) to values.

To remove a property from an object in JavaScript you use the delete operator:

const o = { lastName: 'foo' }
o.hasOwnProperty('lastName') // true
delete o['lastName']
o.hasOwnProperty('lastName') // false

Note that when delete is applied to an index property of an Array, you will create a sparsely populated array (ie. an array with a missing index).

When working with instances of Array, if you do not want to create a sparsely populated array - and you usually don't - then you should use Array#splice or Array#pop.

Note that the delete operator in JavaScript does not directly free memory. Its purpose is to remove properties from objects. Of course, if a property being deleted holds the only remaining reference to an object o, then o will subsequently be garbage collected in the normal way.

Using the delete operator can affect JavaScript engines' ability to optimise code.

Ben Aston
  • 53,718
  • 65
  • 205
  • 331
Dennis C
  • 24,511
  • 12
  • 71
  • 99
  • 20
    This will cause problems if used on an Array object instance to remove an existing element, e.g. `delete myArray[0]`. See http://stackoverflow.com/a/9973592/426379 and [Deleting array elements](https://developer.mozilla.org/en/JavaScript/Reference/Operators/delete#Deleting_array_elements) – Saul Apr 02 '12 at 09:43
  • 5
    What problems will be caused? – Gottox Apr 02 '12 at 10:01
  • 28
    @Gottox - The `length` property of an Array object remains unchanged. – Saul Apr 02 '12 at 10:53
  • 12
    @Saul: there *would* be problems if `myArray` was really used as an array - but it is not (`myArray` is unfortunate name), it is an object. So in this case `delete` is OK. Note that even if it was created as `new Array()` and used as associative array it would still be OK. Your warning is still something to be aware of if one is using real arrays though. – johndodo Apr 04 '12 at 07:47
  • 2
    @johndodo - True. That is why I started my initial comment with _This will cause problems **if** used on an **Array** object instance_. I nevertheless prefer an approach which performs correctly in all cases, see my answer below. – Saul Apr 04 '12 at 09:19
  • @Saul: see my comment below your answer. – johndodo Apr 04 '12 at 13:33
  • @kamal - no. What you want can be found [here](http://stackoverflow.com/questions/5933157/how-to-remove-an-html-element-using-javascript) –  Jan 16 '13 at 22:04
  • Is it properly to use it if element does not exists in array? – Ivan Kochurkin Feb 17 '13 at 12:27
  • Does this also delete referenced objects? What if myArray["lastname"] was a reference? – whiterook6 Jun 02 '14 at 20:45
  • 1
    @whiterook6 There is nothing "destructor" in Javascript. The behavior of "delete" is simple and just make the following variable undefined. – Dennis C Jul 01 '14 at 06:11
  • It works on objects. Arrays will have undefined values. – pronebird Aug 26 '14 at 13:44
  • What happens when you try to delete an attribute that doesn't exist? – Kevin Wheeler Jul 21 '15 at 17:26
  • What if I want to delete 'lastname' from 3D array? – Vaishnavi Patel Mar 06 '19 at 09:49
  • JavaScript does not have multidimensional arrays. Nested arrays are possible, however. – Ben Aston Apr 19 '20 at 10:14
95

All objects in JavaScript are implemented as hashtables/associative arrays. So, the following are the equivalent:

alert(myObj["SomeProperty"]);
alert(myObj.SomeProperty);

And, as already indicated, you "remove" a property from an object via the delete keyword, which you can use in two ways:

delete myObj["SomeProperty"];
delete myObj.SomeProperty;

Hope the extra info helps...

Jason Bunting
  • 58,249
  • 14
  • 102
  • 93
  • 12
    should be noted that the dot notation doesn't work if the property isn't a simple term. i.e. `myObj['some;property']` works, but `myObj.some;property` wouldn't (for obvious reasons). Also it might not be obvious that you can use a variable in the bracket notation, i.e. `var x = 'SomeProperty'; alert(myObj[x])` – Kip Apr 27 '11 at 03:48
  • 2
    "All objects in JavaScript are implemented as hashtables/associative arrays. " - false. V8 prefers to store an object as a hidden class + densely packed fields. Only if you do weird stuff to them (such as removing fields) it gives up and uses a hash map behind the scenes. – John Dvorak Aug 19 '15 at 06:08
  • 6
    @JanDvorak - hey, you recognize when this answer was originally written, yeah? That description was and still is sufficient for most purposes. That said, I understand being tediously pedantic. :) – Jason Bunting Nov 10 '15 at 20:23
43

None of the previous answers address the fact that JavaScript does not have associative arrays to begin with - there is no array type as such, see typeof.

What JavaScript has, are object instances with dynamic properties. When properties are confused with elements of an Array object instance then Bad Things™ are bound to happen:

Problem

var elements = new Array()

elements.push(document.getElementsByTagName("head")[0])
elements.push(document.getElementsByTagName("title")[0])
elements["prop"] = document.getElementsByTagName("body")[0]

console.log("number of elements: ", elements.length)   // Returns 2
delete elements[1]
console.log("number of elements: ", elements.length)   // Returns 2 (?!)

for (var i = 0; i < elements.length; i++)
{
   // Uh-oh... throws a TypeError when i == 1
   elements[i].onmouseover = function () { window.alert("Over It.")}
   console.log("success at index: ", i)
}

Solution

To have a universal removal function that does not blow up on you, use:

Object.prototype.removeItem = function (key) {
   if (!this.hasOwnProperty(key))
      return
   if (isNaN(parseInt(key)) || !(this instanceof Array))
      delete this[key]
   else
      this.splice(key, 1)
};

//
// Code sample.
//
var elements = new Array()

elements.push(document.getElementsByTagName("head")[0])
elements.push(document.getElementsByTagName("title")[0])
elements["prop"] = document.getElementsByTagName("body")[0]

console.log(elements.length)                        // Returns 2
elements.removeItem("prop")
elements.removeItem(0)
console.log(elements.hasOwnProperty("prop"))        // Returns false as it should
console.log(elements.length)                        // returns 1 as it should
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Saul
  • 17,973
  • 8
  • 64
  • 88
  • 9
    This solution has two issues: it hides the fact that arrays and objects are entirely different beasts in JS (you know it, but apparently OP doesn't) and it uses prototypes. OP would be better off if he learned about arrays and objects (and would name his variables accordingly) - trying to hide the differences between the two will only get him in more trouble. IMHO of course. – johndodo Apr 04 '12 at 13:38
  • 2
    @johndodo - all `Array`s in JS are objects, try `typeof new Array();` or `typeof []` to verify. `Array` is simply a certain kind of an object and not at all a "different beast". In JS, objects are distinguished by their constructor name and prototype chain, see [Prototype-based programming](http://en.wikipedia.org/wiki/Prototype-based_programming). – Saul Apr 05 '12 at 06:53
  • 11
    You are missing the point. I know that arrays are objects too, but that doesn't mean it is wise to use them as such. Programmer should decide if he wants to use something as array (with push, pop, [],...) or as object/"associative array". Mix and match is not a good recipe, precisely because of the problems your solution is trying to hide. If you decide in advance which design pattern to use (array or object) there will be no such problems. – johndodo Apr 05 '12 at 08:06
  • 9
    @johndodo - What problems specifically are you talking about? The purpose of above code is to adresses the deficiency `delete` operator has in regards to `Array` by providing a simple polymorphic function. – Saul Apr 05 '12 at 09:25
  • 1
    `delete` does not have a deficiency. `delete` is designed to remove properties. That's it. Applying the delete operator to an index of an array removes that index. What more need it do? You are left with a sparse array, which is a feature of the language. If you don't want a sparse array, don't delete the index: use `splice` or `pop`. – Ben Aston Apr 19 '20 at 10:18
  • 1
    @BenAston Yeah looking at it now after all these years I agree. Sparse arrays are indeed a feature of the language and delete is indeed simply designed to delete properties. Now all I need to do is to figure out how to find the motivation for deleting an answer which has netted me around 450 points of reputation :-) – Saul Apr 19 '20 at 20:29
  • @BenAston Yes.. or 442 points to be super exact. So who knows, maybe some of those upvotes were given not to the "workaround" but to some useful insights in general :-) In any case, thanks for noticing the misinformed parts and clarifying! – Saul Apr 20 '20 at 14:40
40

That only deletes the object, but it still keeps the array length the same.

To remove the element from the array, you need to do something like:

array.splice(index, 1);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bipin
  • 473
  • 4
  • 2
  • 12
    Indeed, but in this case an array is not being used, just a plain old object, thus it has no length or splice method. – MooGoo Sep 13 '10 at 03:48
  • 2
    @Andreaa Panagiotidis Except when we're not talking about Arrays, in which case it's wrong 100% of the time – Drenai May 31 '18 at 01:32
22

While the accepted answer is correct, it is missing the explanation why it works.

First of all, your code should reflect the fact that this is not an array:

var myObject = new Object();
myObject["firstname"] = "Bob";
myObject["lastname"] = "Smith";
myObject["age"] = 25;

Note that all objects (including Arrays) can be used this way. However, do not expect for standard JavaScript array functions (pop, push, etc.) to work on objects!

As said in accepted answer, you can then use delete to remove the entries from objects:

delete myObject["lastname"]

You should decide which route you wish to take - either use objects (associative arrays / dictionaries) or use arrays (maps). Never mix the two of them.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
johndodo
  • 17,247
  • 15
  • 96
  • 113
  • 8
    Very good answer. I would only advise anyone reading this that Arrays in javascript should not be abstracted as 'maps', but rather 'lists'. That's because you should not try to have control over the index of the elements when using arrays. If you try that...well, just don't :D – rodolfo42 May 04 '14 at 03:13
12

There is an elegant way in the Airbnb Style Guide to do this (ECMAScript 7):

const myObject = {
  a: 1,
  b: 2,
  c: 3
};
const { a, ...noA } = myObject;
console.log(noA); // => { b: 2, c: 3 }

Copyright: https://codeburst.io/use-es2015-object-rest-operator-to-omit-properties-38a3ecffe90

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
paveldroo
  • 828
  • 9
  • 14
9

As other answers have noted, you are not using a JavaScript array, but a JavaScript object, which works almost like an associative array in other languages except that all keys are converted to strings. The new Map stores keys as their original type.

If you had an array and not an object, you could use the array's .filter function, to return a new array without the item you want removed:

var myArray = ['Bob', 'Smith', 25];
myArray = myArray.filter(function(item) {
    return item !== 'Smith';
});

If you have an older browser and jQuery, jQuery has a $.grep method that works similarly:

myArray = $.grep(myArray, function(item) {
    return item !== 'Smith';
});
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    perfect explanation. I used filter to achieve the desired result. Would you explain how the return item works to remove the object from the array. I'm assuming it returns the array as long as it doesn't include the string you included. – Edward Jan 19 '18 at 16:05
6

Use method splice to completely remove an item from an object array:

Object.prototype.removeItem = function (key, value) {
    if (value == undefined)
        return;

    for (var i in this) {
        if (this[i][key] == value) {
            this.splice(i, 1);
        }
    }
};

var collection = [
    { id: "5f299a5d-7793-47be-a827-bca227dbef95", title: "one" },
    { id: "87353080-8f49-46b9-9281-162a41ddb8df", title: "two" },
    { id: "a1af832c-9028-4690-9793-d623ecc75a95", title: "three" }
];

collection.removeItem("id", "87353080-8f49-46b9-9281-162a41ddb8df");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
HarpyWar
  • 113
  • 1
  • 5
  • 1
    this is a more generic solution, can be added to your js file and the method will be available to all arrays, not just one array. – Hussain Jun 29 '17 at 12:24
6

You can do the following if you want a more functional and elegant approach:

const o = { firstName: "foo", lastName: "bar" };
const { lastName, ...removed } = o;
lastName // bar
removed // { firstName: "foo" }

Note that the value of removed will be undefined if there are no items left in the object.

Kenan Soylu
  • 116
  • 2
  • 7
5

If, for whatever reason, the delete key is not working (like it wasn't working for me), you can splice it out and then filter the undefined values:

// To cut out one element via arr.splice(indexToRemove, numberToRemove);
array.splice(key, 1)
array.filter(function(n){return n});

Don’t try and chain them since splice returns removed elements;

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Leon
  • 5,701
  • 3
  • 38
  • 38
5

By using the "delete" keyword, it will delete the array element from array in JavaScript.

For example,

Consider following statements.

var arrayElementToDelete = new Object();

arrayElementToDelete["id"]           = "XERTYB00G1";
arrayElementToDelete["first_name"]   = "Employee_one";
arrayElementToDelete["status"]       = "Active";

delete arrayElementToDelete["status"];

The last line of the code will remove the array element whose key is "status" from the array.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ravindra Miyani
  • 360
  • 6
  • 14
5

You are using Object, and you don't have an associative array to begin with. With an associative array, adding and removing items goes like this:

    Array.prototype.contains = function(obj)
    {
        var i = this.length;
        while (i--)
        {
            if (this[i] === obj)
            {
                return true;
            }
        }
        return false;
    }


    Array.prototype.add = function(key, value)
    {
        if(this.contains(key))
            this[key] = value;
        else
        {
            this.push(key);
            this[key] = value;
        }
    }


    Array.prototype.remove = function(key)
    {
        for(var i = 0; i < this.length; ++i)
        {
            if(this[i] == key)
            {
                this.splice(i, 1);
                return;
            }
        }
    }



    // Read a page's GET URL variables and return them as an associative array.
    function getUrlVars()
    {
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');

        for(var i = 0; i < hashes.length; i++)
        {
            hash = hashes[i].split('=');
            vars.push(hash[0]);
            vars[hash[0]] = hash[1];
        }

        return vars;
    }


    function ForwardAndHideVariables() {
        var dictParameters = getUrlVars();

        dictParameters.add("mno", "pqr");
        dictParameters.add("mno", "stfu");

        dictParameters.remove("mno");


        for(var i = 0; i < dictParameters.length; i++)
        {
            var key = dictParameters[i];
            var value = dictParameters[key];
            alert(key + "=" + value);
        }
        // And now forward with HTTP-POST
        aa_post_to_url("Default.aspx", dictParameters);
    }


    function aa_post_to_url(path, params, method) {
        method = method || "post";

        var form = document.createElement("form");

        // Move the submit function to another variable
        // so that it doesn't get written over if a parameter name is 'submit'
        form._submit_function_ = form.submit;

        form.setAttribute("method", method);
        form.setAttribute("action", path);

        for(var i = 0; i < params.length; i++)
        {
            var key = params[i];

            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
        }

        document.body.appendChild(form);
        form._submit_function_(); // Call the renamed function
    }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Stefan Steiger
  • 78,642
  • 66
  • 377
  • 442
4

You can remove an entry from your map by explicitly assigning it to 'undefined'. As in your case:

myArray["lastname"] = undefined;

Amytis
  • 91
  • 4
  • 1
    This could be useful in cases where one isn't sure whether the key exists in the dictionary, but wants to sanitize it in case it does. Correct me if I'm wrong Amytis. – Hassan Baig Jun 12 '18 at 21:27
3

We can use it as a function too. Angular throws some error if used as a prototype. Thanks @HarpyWar. It helped me solve a problem.

var removeItem = function (object, key, value) {
    if (value == undefined)
        return;

    for (var i in object) {
        if (object[i][key] == value) {
            object.splice(i, 1);
        }
    }
};

var collection = [
    { id: "5f299a5d-7793-47be-a827-bca227dbef95", title: "one" },
    { id: "87353080-8f49-46b9-9281-162a41ddb8df", title: "two" },
    { id: "a1af832c-9028-4690-9793-d623ecc75a95", title: "three" }
];

removeItem(collection, "id", "87353080-8f49-46b9-9281-162a41ddb8df");
2

It's very straightforward if you have an Underscore.js dependency in your project -

_.omit(myArray, "lastname")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vatsal
  • 3,803
  • 2
  • 19
  • 19
0

For "Arrays":

If you know the index:

array.splice(index, 1);

If you know the value:

function removeItem(array, value) {
    var index = array.indexOf(value);
    if (index > -1) {
        array.splice(index, 1);
    }
    return array;
}

The most upvoted answer for delete works well in case of objects but not for the real arrays. If I use delete it removes elements from loops but keeps the element as empty and length of array wont change. This may be a problem in some scenarios.

For example, if I do myArray.toString() on myArray after removal via delete, it creates an empty entry, i.e. ,,.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Arvind K.
  • 1,184
  • 2
  • 13
  • 27
0

The only working method for me:

function removeItem (array, value) {
    var i = 0;
    while (i < array.length) {
        if(array[i] === value) {
            array.splice(i, 1);
        } else {
            ++i;
        }
    }
    return array;
}

Usage:

var new = removeItem( ["apple","banana", "orange"],  "apple");
// ---> ["banana", "orange"]
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
T.Todua
  • 53,146
  • 19
  • 236
  • 237
-2
var myArray = newmyArray = new Object();
myArray["firstname"] = "Bob";
myArray["lastname"] = "Smith";
myArray["age"] = 25;

var s = JSON.stringify(myArray);

s.replace(/"lastname[^,}]+,/g, '');
newmyArray = JSON.parse(p);

Without looping/iterates we get the same result.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131