remove object from array with just the object's reference - javascript

Suppose I have an array of objects called MyArray and that a certain function returns a reference for a particular element within that array; something like this:
MyArray = [Object1, Object2, ..., Objectn];
function DoWork() {
var TheObject = GetTheObject(SomeParamter);
}
At this point, TheObject points to a certain element in the array. Suppose I want to remove this element from MyArray, is this possible without having to reloop through the array to get the index of the element?
I'm looking for something like splice that would work with the reference to the element rather than the index of the element.

Simply use Array.prototype.indexOf:
let index = MyArray.indexOf(TheObject);
if(index !== -1) {
MyArray.splice(index, 1);
}
Keep in mind that if targeting IE < 9 you will need to introduce a polyfill for indexOf; you can find one in the MDN page.

Related

Using push() to copy one array into another

Let's assume I have a function like this
function createMultiDimArray() {
let results = [];
let current = [];
for (let i = 1; i <= 10; i++) {
current.push(i);
if (i % 2 === 0) {
results.push(current);
current = [];
}
}
return results;
}
When I execute it
let arr = createMultiDimArray();
arr will look like this
[[1,2][3,4][5,6][7,8][9,10]]
I have tested it in multiple browsers and it seems to work. So apparently push() is creating a copy of the array passed to it instead of just using the reference, because otherwise arr would look like this (as current === [] when the function ends)
[[],[],[],[],[]]
I have searched the internet but I haven't found anything about this behavior of push(). So my question is: Is it safe to use push() to copy one array into another?
push does not copy the array (or whatever argument it's given).
Rather, the line
current = [];
creates a new array object and assigns it to the array reference current. From your analysis, I guess you assumed it would empty the existing array object referred to by current, but that's not the case.
No, in the code you are pushing the values into result using results.push(current);, and after that you create a new current array using current = [];. So after every even number you'll get sets of numbers pushed into results.

How to get all children of a subArray in Javascript

So here's my problem:
So this is what my array looks like, I have shown a fragment of it here (from the console window).
It's overall pretty basic right? Except for it's indexing. As you see the first has value "1" and let's say the second has value "4". As for it's subarrays, these have custom indexes too.
Therefore, the old fashioned:
for(i=0; i<array.length; i++){
someVar = array[i];
//do something
}
won't work.
I get the 1 or 4 from iterating through another array, so don't need to get those.
I want to get all subArrays(not the further nested subArrays, only the second level).
So basicly what I want is something like this(is there something like this?):
array[someIndex].children.forEach(
//do something with **this**
)
To make it more practical for you:
So I know that the first array has index 1. How can I get the values of cat1 and cat2 without knowing it has index 2 (this could also be 6 or 42 for example). In this case, the first array only has one subArray but I would like to make it work for multiple subArrays. (to clarify, select cat1, cat2 from the second level subarray with, in this case, index 2)
Thanks in advance, any help is appreciated!
Evoc
Those aren't arrays. You have
[ { "1": { etc...
which is an array containing an object containing multiple other objects. You can't really use a for(i=...) loop for this, because your keys aren't sequential. You should use a for ... in loop instead:
arr = [{"1":{....}}];
for (i in arr[0]) {
for (j in arr[0][i]) {
console.log(arr[0][i][j]['msg']);
}
}
Use Object.getOwnPropertyNames to get the properties ordered with the integer indices first, from smallest to greatest. Iterate them to get msg1.
var array = {"1":{"3":{"5":{"data":"someData","moreData":"someMoreData"},"msg1":"hello world","msg2":"foo equals bar"},"5":{"8":{"data":"someData","moreData":"someMoreData"},"msg1":"world hello","msg2":"bar equals foo"},"your_name":"jimmy","your_msg":"hello world"},"4":{"3":{"5":{"data":"someData","moreData":"someMoreData"},"msg1":"hello world","msg2":"foo equals bar"},"5":{"8":{"data":"someData","moreData":"someMoreData"},"msg1":"world hello","msg2":"bar equals foo"},"your_name":"billy","your_msg":"foo equals bar"}};
for(let key of Object.getOwnPropertyNames(array[1])) {
if(Object(array[1][key]) !== array[1][key]) break;
console.log('msg1 of "'+key+'": ' + array[1][key].msg1);
}
console.log('your_msg: ' + array[1].your_msg);
The example you showed it's an array with only one index, inside of this index there are nested objects, you could iterate them using the property iterator (foreach). You have to go to the second level tho, since the values you need are there.
for (var key in object) {
for(var anotherKey in object[key]) {
//check for undefined
if(object[key][anotherKey].hasOwnProperty('msg')) {
//code
}
}
}
{ } - declaring objects (literal)
[ ] - declaring arrays

JSON Parse splice issue

I can't seem to work out why splice isn't working correctly in this instance.
I have read countless stack overflow examples of splice and I can't seem to see an issue.
This code should basically remove index 14, from the first item(and only) in the JSON array.
var product_variations = JSON.parse('[{"0":"","1":"","2":"","3":"0.0000","4":"","5":"0.00","6":"0.00","7":"1.00","8":"0","9":"false","10":"false","11":[],"12":"","13":"","14":"Red","15":"Small"}]');
product_variations[0].splice(14, 1);
It does not work because splice is a method available on arrays, not on objects.
And this is an object:
{"0":"","1":"","2":"","3":"0.0000","4":"","5":"0.00","6":"0.00","7":"1.00","8":"0","9":"false","10":"false","11":[],"12":"","13":"","14":"Red","15":"Small"}
Actually you get an error like:
TypeError: undefined is not a function (evaluating 'product_variations[0].splice(14, 1)')
You can use delete instead or convert it to an array:
delete product_variations[0]["14"]
To convert it to an array you could try:
function objectToArray(p){
var keys = Object.keys(p);
keys.sort(function(a, b) {
return a - b;
});
var arr = [];
for (var i = 0; i < keys.length; i++) {
arr.push(p[keys[i]]);
}
return arr;
}
var product_variations = JSON.parse('[{"0":"","1":"","2":"","3":"0.0000","4":"","5":"0.00","6":"0.00","7":"1.00","8":"0","9":"false","10":"false","11":[],"12":"","13":"","14":"Red","15":"Small"}]');
var arr = objectToArray(product_variations[0]);
arr.splice(14, 1);
Use the "delete" keyword in Javascript.
delete myArray["lastname"];
As mentioned, it does not work because your object is just a list and what you are using is a object (assoc array)
.splice
The splice() method adds/removes items to/from an array, and returns the removed item(s).
Note: This method changes the original array.
delete
The delete operator removes a property from an object.
So your code should look like
delete product_variations[0]["14"]
Remember that the 14 number is a string, not a number, as you have written in your code, since that's the name of the element in your array.
Nevertheless, I highly recommend you, after having seen the code you are managing, to switch that to a list, since the keywords are only like the indices of a normal list (with the exception that they start in 1)

Using indexOf to remove an Object from a list?

So, I have seen this piece of code:
removeOrder = (order) ->
index = listOfOrders.indexOf(order)
if index isnt -1
listOfOrders.splice index, 1
where order is an object like this:
order = {
id: whatever
field1: whatever
...
}
This is working now because the order that is passed as argument is referencing some object in listOfOrders, something like removeOrder(listOfOrders[i]). But my question is, is this safe? I mean, I think it would be better to iterate over the list of orders and search for an object with the same id, for example, and remove it.
As far as I know indexOf is Ok when the object we are searching for is a "simple" object (a number, a string, etc.).
According to These docs for indexOf, indexOf uses strict equality ===.
var a = {id:1};
var b = {id:1};
a === a; // this is true
a === b; // this is false
So its safe to in general for objects
You do need to check that indexOf != -1 before the splice though
var removeOrder = function(order)
{
var index = listOfOrders.indexOf(order);
if (index != -1)
return listOfOrders.splice(index, 1); //for chaining?
return listOfOrders;
}
It's safe to use indexOf if the intended purpose is to remove an object from the array by it's reference.
If you want to remove first object by id let's say, you would use something like:
var removeOrderById = function(orderId)
{
var orders = listOfOrders.filter(function(item)
{
return item.id == orderId;
});
if (orders.length > 0)
{
var index = listOfOrders.indexOf(orders[0]);
return listOfOrders.splice(index, 1); //for chaining?
}
return listOfOrders;
}
Conclusion: it's all about the use case.
The function works as inteded assuming that there is exactly one reference to the object in the array.
If the object isn't in the array (or you are calling it with a clone of an object in the array), the index will be -1 and the splice call will remove the last item in the array instead. As this is not a reasonable behaviour, there should really be a check for that (which I see that you added).
The indexOf method works reliably for object references, but it natually has to be looking for the same object.
Looking for an object with a specific propery value would also work, but it goes with the same assumptions; the value has to occur exactly once in the array to work as intended.

Using a variable as an array parameter in javascript?

I want to use a variable as the index parameter in an array but for some reason it's coming up as "undefined" when I do it this way. Any ideas?
var object_number = [];
var x = 1;
function create_new_object()
{
object_number[x] = new happy_object();
x++;
}
Array indices start at zero in JavaScript. When x starts at 1, there's an undefined element in the first position of the array. Start at x=0 instead.
There's a better way to do this, however. Instead of manually keeping track of the last element in the list, you can just use Array.push() to add a new element onto the end.
var object_number = [];
function create_new_object()
{
object_number.push(new happy_object());
}
When you want to find out how many elements are in the array, use Array.length (or the number returned by Array.push()).
Further reference: Array # MDC.
your object_number is an empty array with no elements. Hence you are getting this error.
To add elements to array, you need to use push method.
object_number.push(new happy_object() );
Also you need to start your array index from 0 instead of 1. i.e. your x should be 0.
In addition to the previous answers:
Unlike "normal" languages (which use block-scope), javascript uses function-scope.
So be shure x exists in side your function-scope when you use it like that.
you can't mess with array keys too too much in js - if you want a more solid, definable relationship, you'll need to mimic an associative array by doing:
var object_number = {};
var x = 1;
function create_new_object() {
object_number[x] = new happy_object();
}
Also, I'd combine your var statements. Makes variable/function hoisting a bit clearer.
var object_number = {}
, x = 1;

Categories

Resources