Swapping elements in an array of objects [duplicate] - javascript

This question already has answers here:
Javascript swap array elements
(33 answers)
Closed 9 years ago.
I have an array of objects and I want to swap the position of two elements in the array.
I tried this:
var tempObject = array.splice(index, 1, array[index + 1]);
array.splice(index+1, 1, tempObject);
But it doesn't seem to work properly as it results in some weird errors. For example, I am unable to use methods of the object. Calling array[x].getName results in an error.
Can any body lend a helping hand here?
Just in case it is important, I have used object.prototype to add the methods.

The bug in your code is that splice returns an array of items, not a single item. Since you are extracting a single item, you could do:
var tempObject = array.splice(index, 1, array[index + 1])[0]; // get the item from the array
array.splice(index+1, 1, tempObject);
This answer provides a shorter version, also using splice:
array[index] = array.splice(index+1, 1, array[index])[0];
Another very interesting answer is both short and fast:
function identity(x){return x};
array[index] = identity(array[index+1], array[index+1]=array[index]);

JSFIDDLE
var array_of_numbers = [5,4,3,2,1,0],
swap = function(array,a,b){var tmp=array[a];array[a]=array[b];array[b]=tmp;};
swap(array_of_numbers,0,4);
// array_of_numbers now is [1,4,3,2,5,0]
Or you can do add the function to the Array.prototype:
JSFIDDLE
Array.prototype.swap = function(a,b){ var tmp=this[a];this[a]=this[b];this[b]=tmp;};
var array_of_numbers = [5,4,3,2,1,0];
array_of_numbers.swap(0,4);
// array_of_numbers now is [1,4,3,2,5,0]

Related

Javascript: Subarrays contain reference to other arrays even though parent is its own array? [duplicate]

This question already has answers here:
How do you clone an array of objects in JavaScript?
(40 answers)
What is the most efficient way to deep clone an object in JavaScript?
(67 answers)
Closed 4 years ago.
OK.
Let me try to say this in some sort of comprehensible manner. I'm an amateur programmer writing my own take on a neural network in javascript. (Without having seen the code for a neural network before)
I was having problems with an array changing when I was trying to change a copy of the array. (Not the original)
I soon realized after rereading what I'd written that when you assign an identifier to an array it doesn't make the identifier a new object with a copy of the array. Instead, it makes a reference to the original array object, for example:
var arr = [1,2,3];
var arr2 = arr;
arr2[0] = 9;
alert(arr);
//Alerts "9,2,3"
With this mind, I googled and found a quick solution:
var arr = [1,2,3];
var arr2 = arr.slice();
arr2[0] = 9;
alert(arr);
//Alerts "1,2,3"
So I changed this in my actual project expecting to see my work completed, but no! I was getting the exact results as before where my array was changing even though it was not supposed to.
After much effort at debugging, I finally worked out that the problem here is that I have a large array of subarrays, which in turn have subarrays.
In code this looks like:
var arr = [
[[1],[2]],
[[4],[5]],
[[7],[8]]
];
As you can see, there is one big array that contains 3 smaller arrays, each of which contains two even smaller arrays, each of which contains a number.
In my project, it's more complicated than this and has a couple more layers but this is a decent representation.
So what did I expect to happen?
var arr = [
[[1],[2]],
[[4],[5]],
[[7],[8]]
];
var other = arr.slice();
other[0][0][0] = "Uh Oh";
alert(arr);
//Outputs "1,2,3,4,5,6,7,8"
What actually happened?
alert(arr);
//Outputs "Uh Oh,2,3,4,5,6,7,8"
Why does this happen?
How can I fix it?
Thanks in advance.
Try following
var arr = [
[[1],[2]],
[[4],[5]],
[[7],[8]]
];
var other = JSON.parse(JSON.stringify(arr));
other[0][0][0] = "Uh Oh";
console.log(arr);
Reasoning
arr.slice() creates different reference for the array, however, any child object/array will still continue to hold the same reference. But you need to change the references of the child object/array as well, for that convert it into a string and then back to object - It will create different references for all the objects.

javascript splice method and return confusion [duplicate]

This question already has answers here:
js. splice returns removed item?
(4 answers)
Closed 11 months ago.
So I was trying to create a javascript function to remove n elements from the beginning of an array, the following is the code:
function slasher(arr, howMany) {
arr.splice(0, howMany);
return arr;
}
slasher([1, 2, 3], 2);
Question:
Can someone explain to me why when I change the code inside the function to one line: return arr.splice(0, howMany);, the function would give me [1, 2] instead of [3]?
Thanks!
From docs of splice
Returns
An array containing the deleted elements. If only one element is removed, an array of one element is returned. If no elements are removed, an empty array is returned.
So you are actually getting the deleted elements array rather than the actual array.
Its because splice returns the elements removed but not the array with element removed.
var arr =[1,2,3]
var elementsRemoved = arr.splice(0,2);
elementsRemoved = [1,2] and arr would be [3].
Because splice() returns value and in the same time changes your array.
So when you return arr.splice() - you are returning what's returning this function, but when you return arr - you are returning your new array.
function slasher (arr, howMany){
return arr.splice(howMany, arr.length)
}
console.log(slasher([0,1,2,3,4],2))
splice syntax is splice(index, number of elemnets to be removed from that index)
or
function slasher (arr, howMany){
return arr.slice(howMany, arr.length)
}
console.log(slasher([0,1,2,3,4],3))

How to get last item in array Node.js? [duplicate]

This question already has answers here:
Get the last item in an array
(59 answers)
Closed 5 years ago.
I am new to node.js and JavaScript so this question might be quite simple but I cannot figure it out.
I have a lot of items in an array but only want to get the last item. I tried to use lodash but it somehow does not provide me with the last item in the array.
My array looks like this now:
images : ['jpg.item_1', 'jpg.item_2', 'jpg.item_3', ..., 'jpg.item_n']
and i want to get:
images : 'jpg.item_n'
Using lodash I am getting:
images : ['g.item_1', 'g.item_2', 'g.item_n']
It looks like I am just getting the last letter in jpg, i.e. 'g'.
My code using lodash looks like this:
const _ = require('lodash');
return getEvents().then(rawEvents => {
const eventsToBeInserted = rawEvents.map(event => {
return {
images: !!event.images ? event.images.map(image => _.last(image.url)) : []
}
})
})
Your problem is that you're using _.last inside map. This will get the last character in the current item. You want to get the last element of the actual Array.
You can do this with pop(), however it should be noted that it is destructive (will remove the last item from the array).
Non-destructive vanilla solution:
var arr = ['thing1', 'thing2'];
console.log(arr[arr.length-1]); // 'thing2'
Or, with lodash:
_.last(event.images);
Use .pop() array method
var images = ['jpg.item_1', 'jpg.item_2', 'jpg.item_3', 'jpg.item_n'];
var index= images.length - 1; //Last index of array
console.log(images[index]);
//or,
console.log(images.pop())// it will remove the last item from array
Although Array.prototype.pop retrieves the last element of the array it also removes this element from the array. So one should combine Array.prototype.pop with Array.prototype.slice:
var images = ['jpg.item_1', 'jpg.item_2', 'jpg.item_3', 'jpg.item_n'];
console.log(images.slice(-1).pop());

Array with numbers 1-20 [duplicate]

This question already has answers here:
How to create an array containing 1...N
(77 answers)
Closed 9 years ago.
I'm brand new to javascript. I was working through a problem earlier where I needed an array that included the numbers 1 thru 20.
I did this with the following:
var numberArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
QUESTION:
I can't help but think that this is not efficient (and certainly not scalable). Is there a way to create an array that automatically populates with sequential values between 1 and 20, or 1 and 1000 for instance?
Here's a oneliner:
var myArr = Array(20).join().split(',').map(function(a){return this.i++},{i:1});
or a tiny bit shorter:
var myArr = (''+Array(20)).split(',').map(function(){return this[0]++;}, [1]);
Both methods create an empty Array with 20 empty elements (i.e. elements with value undefined). On a thus created Array the map method can't be applied 1, so the join (or string addition) and split trick transforms it to an Array that knows it. Now the map callback (see the MDN link) does nothing more than sending an increment of the initial value ({i:1} or [1]) back for each element of the Array, and after that, myArr contains 20 numeric values from 1 to 20.
Addendum: ES20xx
[...Array(21).keys()].slice(1);
Array.map => See also...
See also this Stackblitz project.
1 Why not? See this SO answer, and this one for a more profound explanation
You could use a simple loop to do what you want;
var numberArray = [];
for(var i = 1; i <= 20; i++){
numberArray.push(i);
}
console.log(numberArray);

How to write 'for-in' in JavaScript ? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Functional approach to basic array construction
I am new to js. I just want to know which one is the right approach. Below I have posted my code.
var doubles = (i*20 for (i in it));
var doubles ={i*20 for (i in it)};
Thanks
You should use ordinary for loops when iterating over arrays. for...in is used for iterating over object properties.
So, the correct way is:
for (var i = 0; i < array.length; ++i) {
// do something
}
To iterate over object properties:
for (var prop in obj) {
// do something with prop
}
Assuming it is an array, you can use .map():
var doubles = it.map(function(i){ return i*20; });
Also you might want to have a look at how to write List/Array comprehensions in JavaScript
Assuming you want to use Mozilla's Generator expressions (where it is an existing Iterator), you need to use square brackets:
var twentyfolds = [i*20 for (i in it)];
For future reference, ECMAScript 6 (aka Harmony) will most likely introduce a new sane way of iterating over objects (arrays included):
for(var x of array) {
// do something with x
}
It will also introduce array comprehensions and generator expressions to the core language:
var arr = [1, 2, 3];
console.log([i*20 for (i of arr)])
Both of these options are syntax errors. If 'it' is a list, then you can iterate through it with a for loop or the forEach method. In your case however, it looks like you are really looking for the map method.
var doubles = it.map(function (i) { return i * 20; });

Categories

Resources