Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve the "TypeError: array.splice is not a function" when 'var array = {}'? [duplicate]

Possible Duplicate:
How to remove a property from a javascript object
JavaScript Hashmap Equivalent

I am using jQuery and I am handling a variable this way:

var array = {};

array[an_object]      = something
array[another_object] = something_else
array[...]            = ...

When I try to run the splice method on the array I get a TypeError: array.splice is not a function. My intent is to remove the an_object "key" and all its content from the array variable.

How can I make that?


Note: When I run the console.log(array[an_object]) (the same is valid for another_object and all other objects) I get:

[Object { label="str1",  value=1 }, Object { label="str2",  value=2 }, { label="strN",  value=N }]
like image 822
user12882 Avatar asked Nov 23 '12 08:11

user12882


People also ask

Why is splice not working on array?

It's not working because you are removing items from the array while looping through the keys. When you remove an item, it will rearrange the other items depending on how the array is implemented internally, and you end up with a loop that doesn't iterate over the keys that you expect.

What is splice method in array?

The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place. To access part of an array without modifying it, see slice() .

How do you splice an array of objects?

splice() JS Array Method. The splice() method is a built-in method for JavaScript Array objects. It lets you change the content of your array by removing or replacing existing elements with new ones. This method modifies the original array and returns the removed elements as a new array.

Does splice return a new array JS?

2. The splice() method changes the original array and slice() method doesn't change the original array.


3 Answers

First of all, name your variables what they are. The name array you're using, is misleading if you use it to create a object.

var myObject = {};  myObject[an_object]      = "xyz"; myObject[another_object] = "abc"; 

Now, you can delete the entry in the object with the delete statement:

delete myObject[an_object]; // Returns true / false if the deletion is a success / failure console.log(myObject[an_object]) // Returns undefined 

Now, that said, this will not work like you'd expect. myObject[an_object] will contain "abc"
Don't use objects as keys. Use strings, instead.
This is because of the fact that any parameter entered in the [] will be converted to string. So actually, you're entering myObject["[object Object]"]

like image 145
Cerbrus Avatar answered Sep 29 '22 05:09

Cerbrus


I am a little confused about the way you are building your object, because an_object used as a key would have to be a string value for a key. Assuming you do so, this should work by deleting the undesired property of the object.

var array = {};  array['an_object'] = "something" array['another_object'] = "something_else"  delete(array.an_object)  console.log(array) // Object { another_object = "something_else" } 

EDIT

As detailed in comments, if the issue is that objects are being used as keys for another object (in this case confusingly named array), then the problem is that an object is first converted to it's string representation to be used in the context of an object key. Therefore, all objects used as keys, will actually refer to one key called [object Object], and whichever object you use as a key will overwrite previous ones.

In the example in the question...

array[an_object]      = something array[another_object] = something_else // array: Object { "[object Object]" = "something_else" } 
like image 37
Billy Moon Avatar answered Sep 29 '22 03:09

Billy Moon


To achieve a Dictionary in simple JavaScript is rather tricky, you would need to create an entire constructor to handle this - or use a library that would handle this for you.

By Dictionary I am refering to an object/hash that can use objects as keys. You would need a constructor that would use multiple arrays (one for the key and one for the value) and that would keep them in-sync. You could mimic many of the typical array methods, but as I stated this would be quite a bit of code.

As a simple alternative you can do the following:

function pushToObject(obj, key, value){
  if( !key||!obj ) return false;
  if( !key[''] ) {
    pushToObject.index = pushToObject.index||[];
    key[''] = pushToObject.index.length;
    pushToObject.index.push(key);
  }
  obj[key['']] = value;
  return true;
}

function removeFromObject(obj, key){
  if( !isNaN(key) ) {
    var list = listKeyObjects(obj);
    var item = list[key];
    return removeFromObject(obj,item);
  }
  else if(key) {
    if( !key[''] ){
      return false;
    }
    return delete obj[key['']];
  }
  return false;
}

function listKeyObjects(obj){
  var a = [];
  for(var i in obj){
    a.push(pushToObject.index[i]);
  }
  return a;
}

usage

var array = {}; /// it would be best to change the name of this object
var an_object = {}, another_object = {};

/// add your items to the array object, this handles giving each of your
/// objects used as a key a unique index property. This does mean the objects
/// you use `an_object`, `another_object` are modified.
pushToObject( array, an_object, 'something else' );
pushToObject( array, another_object, 'something other than else' );

console.log(array); /// {0:'something else',1:'something other than else'}

removeFromObject( array, an_object ); /// remove using an object as a key

console.log(array); /// {1:'something other than else'}

removeFromObject( array, 0 ); /// remove using an offset index

console.log(array); /// {}

after thoughts

Obviously the better option is to create your own dedicated constructor for this, but you could improve the above with a bit more code so that it didn't modify the key objects. Instead whenever working with an object as a key you could scan the pushToObject.index for the offset of your key object. I chose to go for the version that modifies your key objects however as it should function faster than having to scan a list every time you make an array modification.

get key function

The above code only shows you how to add and how to remove, it may also be a good idea on getting a particular key object from an offset:

function getKeyObjectAtIndex = function(obj, index){
  var list = listKeyObjects(obj);
  return list[index] ? list[index] : null;
}

console.log(array); /// {0:'something else',1:'something other than else'}

var key = getKeyObjectAtIndex(array, 1);

console.log(key === another_object) /// === TRUE
like image 34
Pebbl Avatar answered Sep 29 '22 05:09

Pebbl