function randOrd() {
return (Math.round(Math.random()) - 0.5)
}
A = [0,1,2,3,4,5,6,7]
var B = A.sort(randOrd)
console.log('A=',A)
console.log('B=',B)
output:
a= [ 3, 4, 0, 1, 6, 2, 5, 7 ]
b= [ 3, 4, 0, 1, 6, 2, 5, 7 ]
I expected a to be the original array and b to be sorted. But they are both equal (sorted), why?
Because the Array.sort() method sorts in-place and then returns the array.
The Javascript sort function sorts the array in place, meaning its modifying the original array and returning it:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
Because you're running the method 'sort' on var A... which firstly will sort A into an order, and then set that data to B... which is why you get identical answers for A and B
Related
I have an array of arrays of arrays and I'm trying to remove an element from a sub-sub array. The problem is the element is removed from all my sub-sub arrays. See code below:
let list = Array(9).fill(Array(9).fill([1,2,3,4,5,6,7,8,9]));
list[0][0].splice(3,1);
console.log(list[0][0],list[2][1],list)
Please let me know if you know how to solve that.
Array.prototype.fill fills the array with the exact same value that was provided to it. This is not a problem when filling the array with immutable values (like numbers, strings) but it's usually a problem with mutable values (like objects, arrays).
So, if you mutate one value in the array you would notice the change at all other places because all of them refer to the exact same value. Refer to example below for better understanding.
let nums = [1];
let arr = Array(2).fill(nums);
// mutating nums
nums[0] = 5;
// the change is visible in arr as well
console.log(arr[0]); // [ 5 ]
// and it's visible at both the indicies
console.log(arr[1]); // [ 5 ]
// mutating arr
arr[0][0] = 10;
// change is visible in nums as well
console.log(nums); // [ 10 ]
// and also at index 1
console.log(arr[1]); // [ 10 ]
You can use Array.from instead.
let list = Array.from({ length: 9 }, () =>
Array.from({ length: 9 }, () => [1, 2, 3, 4, 5, 6, 7, 8, 9])
);
list[0][0].splice(3, 1);
console.log(list[0][0]); // [ 1, 2, 3, 5, 6, 7, 8, 9 ]
console.log(list[1][0]); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
This is my first question on stackoverflow, I am new :) learning JS. I have a question. I wrote this function:
function inverseSlice(items, a, b) {
return items.splice(a, b);
}
inverseSlice([1, 2, 3, 4, 5, 6], 2, 4)
(4) [3, 4, 5, 6]
Why this function returns last 4 digits, when according to docs on MDN (which I read 10 times already :P) splice() method should remove here only 2 middle ones (3, 4)? It should return [1, 2, 5, 6]. Am I right? Thank You for all Your help :)
It's doing exactly what it advertises, it "returns an array containing the deleted elements."
function inverseSlice(items, a, b) {
return items.splice(a, b);
}
let array = [1, 2, 3, 4, 5, 6, 7, 8];
// Deletes 4 entries starting at index 2,
// or in other words [3,4,5,6] are snipped
inverseSlice(array, 2, 4);
console.log(array);
Unless you keep a reference to the array you're passing in you'll never observe anything about how it ends up, you'll only get the deleted elements.
splice will
Mutate the original array: remove N items, where N is the third parameter, starting from the start index (first parameter) to the number specified (so here, it'll remove indicies 2 through 5 from the array; indicies 2, 3, 4, and 5, a total of 4 get removed)
Return the removed elements - so, here, that's [3, 4, 5, 6].
The original array is now [1, 2], but you're logging what was returned by .splice, not the original array.
If you wanted [1, 2, 5, 6], you'd want to specify 2 for the 3rd argument (2 items to remove), and then log the original array:
function inverseSlice(items, a, b) {
return items.splice(a, b);
}
const arr = [1, 2, 3, 4, 5, 6];
const removedItems = inverseSlice(arr, 2, 2);
console.log(arr);
console.log(removedItems);
What you are confused about is the arguments to splice, The two arguments that you pass to splice are not the start and end index but the start index and the count of items to be deleted.
Hence in your example it deleted items from 2 to 5 index and returned you the resultant array i.e [3, 4, 5, 6]
As per the docs:
Syntax:
let arrDeletedItems = arr.splice(start[, deleteCount[, item1[, item2[, ...]]]])
Parameters
Start : The index at which to start changing the array.
deleteCount: n integer indicating the number of elements in the array to remove from start.
item1, item2, ... : The elements to add to the array, beginning from start. If you do not specify any elements, splice() will only remove
elements from the array.
This question already has answers here:
Merge/flatten an array of arrays
(84 answers)
Closed 6 years ago.
Below is my array if items that I want to reduce it to a single list of arrays..
var input=[
[
2
],
[
3,
13
],
[
4,
14
],
[
5,
15,
25,
35
]
]
var output=[
2,
3,
13,
4,
14,
5,
15,
25,
35
]
My code:
function reduceArray(item){
for(var i=0;i<item.length;i++){
return i;
}
}
var result=result.map((item)=>{
if(item.length>0){
return reduceArray(item);
}else{
return item;
}
})
which produces the same result.Can anyone please figure out where I'm doing wrong or any other approach to achieve this..Thanks
input.reduce(function(a, x) { return a.concat(x); });
// => [2, 3, 13, 4, 14, 5, 15, 25, 35]
reduce sets the accumulator to the first element (or a starting value if provided), then calls the function with the accumulator and each successive element. The function we provide is concatenation. If we say input is [a, b, c], then the above command will be equivalent to a.concat(b).concat(c). [concat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) produces a new array by smushing two or more arrays together.
EDIT: Actually, there is another possible answer:
Array.prototype.concat.apply(input[0], array.slice(1));
// => [2, 3, 13, 4, 14, 5, 15, 25, 35]
This directly calls concat with multiple arguments; if input is again [a, b, c], then this is equivalent to a.concat(b, c). apply calls a function with a given receiver and arguments; slice will give us just a part of the array, in this case everything starting from the first element (which we need to chop off since it needs to be the receiver of the concat call).
One liner would be
input = [[2],[3,13],[4,14],[5,15,25,35]];
[].concat.apply([],input);
You can use lodash's flattenDeep()
_.flattenDeep([1, [2, [3, [4]], 5]]);
// → [1, 2, 3, 4, 5]
User concat.check this for more information http://www.w3schools.com/jsref/jsref_concat_array.asp
var input=[[2],[3,13],[4,14],[5,15,25,35]];
var output=[];
for(var i = 0; i < input.length; i++)
{
output = output.concat(input[i]);
}
console.log(output);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
use concat is the perfect way
The concat() method is used to join two or more arrays.
This method does not change the existing arrays, but returns a new array, containing the values of the joined arrays.
var newArr = [];
for(var i = 0; i < input.length; i++)
{
newArr = newArr.concat(input[i]);
}
console.log(newArr);
I found many posts on stack overflow about that similar subject but none of them solve this issue here.
<script>
//Array GanginaA contains duplicated values.
//Array GanginaB contains only unique values that have been fetched from GanginaA
GanginaA=[0,1,2,3,4,5,5,6,7,8,9,9];
GanginaB=[0,1,2,3,4,5,6,7,8,9];
var hezi=<!--The Magic Goes Here-->
console.log(hezi);
/*
* Expected Output:
* 5,9
*/
</script>
GanginaA will always be longer or identical to GanginaB so there is no reason to calculate by the value of the longer array length.
GanginaB will always contains unique values that taken from GanginaA so it will always be the shorter array length or identical to GanginaA array.
Now it makes it a lot easier to find doubles.
You can use filter to get the elements like below
GanginaA = [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9];
GanginaB = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var hezi = GanginaB.filter(function (item, index) {
return GanginaA.indexOf(item) !== GanginaA.lastIndexOf(item)
});
console.log(hezi.join(" , ")); // 5, 9
the easier I can think of :
var hezi=[];
for (var i=0;i<GanginaA.length;i++){
hezi[GanginaA[i]] = GanginaA[i];
hezi[GanginaB[i]] = GanginaB[i];
}
hezi = hezi.filter (function(el){return el!=undefined;});
does everything in O(n) actions and not O(n^2)
Javascript's objects have hashmap like behaviour, so you can use them kind of like a set. If you iterate over all the values and set them to be keys within an object, you can use the Object.keys method to get an array of unique values out.
function uniqueValues() {
var unique = {};
[].forEach.call(arguments, function(array) {
array.forEach(function(value) {
unique[value] = true;
});
});
return Object.keys(unique);
};
This function will return the unique elements in any number of arrays, passed as arguments.
uniqueValues([1, 2, 3], [ 1, 1, 1], [2, 2, 2], [3, 3, 3]); // [ 1, 2 3 ]
One drawback to this method is that Javascript coerces all keys to strings, you can turn them back into numbers by changing the return statement to:
return Object.keys(unique).map(Number);
This question already has answers here:
How to extend an existing JavaScript array with another array, without creating a new array
(20 answers)
Closed 8 years ago.
$ node
> A = [0, 1, 23]
[ 0, 1, 23 ]
> B = A
[ 0, 1, 23 ]
> A.splice(0, 3)
[ 0, 1, 23 ]
> B
[]
> A
[]
> A = A.concat([1, 2])
[ 1, 2 ]
> B
[]
This is correct. But, is it possible that after calling concat, B array be equal with A?
I know that there is the loop solution, but what other alternatives are there to add multiple elements in multiple arrays that are equal?
BTW, I don't want to modify B directly (A = B = A.concat(...)).
Paul is correct, you could do:
A.push.apply(A,[1, 2]);
For those of you not aware, Array#push accept variable arguments, and Function#apply converts a variable arguments accepting function to an array accepting function.
You can use Array.prototype.splice itself, like this
var A = [0, 1, 23], B = A;
A.splice.apply(A, [A.length, 0].concat([1, 2]));
console.log(A, B, A === B);
// [ 0, 1, 23, 1, 2 ] [ 0, 1, 23, 1, 2 ] true
Here, A.length and 0 represent the starting position at the array and number of elements to remove respectively.
We concatenate that with the actual array of elements to be inserted. So, the arguments being passed to A.splice would look like this
A.splice(A.length, 0, 1, 2);
As splice does in-place operation, A and B still refer the same object.