Related
If I want to return a multiple values from a function, in an assigment, do I need to use an intermediate array to receive those values?
How am I used to do it in JavaScript:
let f = () => return [1, 2, 3];
let a, b, c, arr;
arr = f();
a = arr[0]; b = arr[1]; c = arr[2]
Is JavaScript like C, returning assignment to the first lhand operator, or is it possible to do something more flexible, like in this example from Ruby (without using loop):
def f
return 1, 2, 3
end
a, b, c = f
My motivation is simply lack of readability in the JavaScript method.
Issues
return not needed in simple arrow function
destructure assignment syntax
let f = () => [1, 2, 3];
let [a, b, c] = f();
console.log(a, b, c)
You can get values from an array either using index or using destructuring . If there are multiple values then you can easily destructure and store it in different variables in a single statement.
let f = () => [1, 2, 3];
//Using Destructuring
const [a, b, c] = f();
console.log(a, b, c);
// Accessing using index
const arr = f();
const m = arr[0];
const n = arr[1];
const o = arr[2];
console.log(m, n, o);
Since you are using an array to return multiple values then you can use either implicitly return in a function of you can explicitly return an array from it
1) Explicitly return
let f = () => {
return [1, 2, 3];
};
const [a, b, c] = f();
console.log(a, b, c);
2) Implicitly return
let f = () => [1, 2, 3];
const [a, b, c] = f();
console.log(a, b, c);
const [a, b] = [1, 2]
// expected to be equal to
// const a = 1
// const b = 2
const [c, d] = [3, 4]
// expected to be equal to
// const c = 3
// const d = 4
[a, b] = [b, a]
// expected Assignment to constant variable error
console.log(a, b, c, d)
// => 1, 2, 2, 1
Can someone explain what is wrong with this code? What happened to variables c and d?
You're not using semi-colons and ASI doesn't always work the way you would like.
Your code is equivalent to this:
const [a, b] = [1, 2];
const [c, d] = [3, 4][a, b] = [b, a];
console.log(a, b, c, d);
[3, 4][a, b] in this case evaluates as [3,4][2] since the second comma is just the comma operator and b === 2. That makes the assignment equivalent to [3,4][2] = [b,a] which results in a temporary array [3,4,[2,1]] being created and the result of the assignment expression [2,1] is then assigned to [c,d].
Try adding semi-colons and you will get the expected results:
const [a, b] = [1, 2];
// expected to be equal to
// const a = 1
// const b = 2
const [c, d] = [3, 4];
// expected to be equal to
// const c = 3
// const d = 4
[a, b] = [b, a];
// expected Assignment to constant variable error
console.log(a, b, c, d);
It's basically a problem with not terminating commands properly with a semi-colon (;). If you add them to the end of each command you will get the proper result.. and also run into the problem where you cannot reassign a and b as they're declared as const.
Instead of:
const [a, b] = [1, 2];
Try:
const a = 1, b = 2;
const c = 3, d = 4;
To swap the values, try something like:
var temp;
temp = a; a = b; b = temp;
I have 2 arrays: A and B, when I change one both change. Is there a way to edit one without changing the other one.
a = [[0,0,0,0,0],[0,0,0,0,0]]
b = [[1,2,3,4,5],[6,7,8,9,10]]
a = b.slice(0)
a[0][0] = 10
console.log(a) /* [[10,2,3,4,5],[6,7,8,9,10]] */
console.log(b) /* [[10,2,3,4,5],[6,7,8,9,10]] */
The a is fine but I need b to stay [[1,2,3,4,5],[6,7,8,9,10]]
When you do splice, you change the reference of a and b, however, the reference of arrays in array b still share references, hence, update your code to following. Use Array.map
a = [[0,0,0,0,0],[0,0,0,0,0]]
b = [[1,2,3,4,5],[6,7,8,9,10]]
a = b.map(x => [...x])
a[0][0] = 10
console.log(a) /* [[10,2,3,4,5],[6,7,8,9,10]] */
console.log(b) /* [[1,2,3,4,5],[6,7,8,9,10]] */
You can use map to slice each array.
a = [[0,0,0,0,0],[0,0,0,0,0]]
b = [[1,2,3,4,5],[6,7,8,9,10]]
a = b.map(o=>o.slice(0));
a[0][0] = 10
console.log(a);
console.log(b);
Doc: map()
You take a shallow copy with Array#slice, which means nested arrays are taken by their object reference.
You could use Array#map with a check for arrays and map these recursively.
const deep = a => Array.isArray(a) ? a.map(deep) : a;
var a = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]],
b = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]];
a = b.map(deep);
a[0][0] = 10;
console.log(a);
console.log(b);
.as-console-wrapper { max-height: 100% !important; top: 0; }
slice(), like Object.freeze() have a shallow scope, so this works:
var a = [1,2,3,4];
var b = a.slice(0);
a[0] = 10;
console.log(b); // [1, 2, 3]
console.log(a); // [10, 2, 3, 4]
But this doesn't work:
var a = [[0,0,0,0,0],[0,0,0,0,0]]; //multidimensional!
var b = [[1,2,3,4,5],[6,7,8,9,10]];
a = b.slice(0);
a[0][0] = 10;
console.log(a);
console.log(b);
Then, the key is go deep with slice(), for or something, Here an example using for:
var a = [];
for (var i = 0, len = b.length; i < len; i++) {
a[i] = b[i].slice();
}
Keep in mind that const won't work:
var a = [[0,0,0,0,0],[0,0,0,0,0]];
const b = [[1,2,3,4,5],[6,7,8,9,10]];// doesn't work
var a = b.slice(0);
a[0][0] = 10; // a changes b
console.log(a);
console.log(b);
The following code produces (in Chrome javascript console)
a: (3) [1, 2, 3] b: (4) [1, 2, 3, 99] c: 4
I expected c to look like b. Why doesn't it?
function snafu(){
var a = [1,2,3];
var b = a.slice();
var c = a.slice().push(99);
b.push(99);
console.log("a:",a," b:",b," c:",c);
}
Array.push() gives you value of Array.length and not array itself
var a = [];
var b = a.push(8); /* returns length of array after pushing value into array */
console.log('a = ', a, ', b = ', b);
Well, remember Array.slice() will return you new Array. So while pushing it on slice(), it'll return you length of the array.
function snafu(){
var a = [1,2,3];
var b = a.slice();
var c = a.slice();
c.push(99);
b.push(99);
console.log("a:",a," b:",b," c:",c);
}
snafu();
variable c will give you new Array so you can do whatever you want with c.
That's it. Easy!!!!
I have four arrays A,B.C, and D. For example:
length of A is 1
length of b is 4
length of C is 1
length of D is 2.
var a = [1];
var b = [2,3,4,5];
var c = [6];
var d = [7,8];
I want to concat those four arrays based on the larger length of the arrays, so the arrays will be in order: b,d,a,c:
Expected result:
[2,3,4,5,7,8,1,6]
[2,3,4,5,1,6,7,8] //also valid, a and c are same length, so can be sorted this way too.
How can I find the larger to lower arrays and concat them from larger to smaller in JavaScript?
It's simple enough using sort and concat:
Array.prototype.concat.apply([], [a, b, c, d].sort(function (a, b) {
return b.length - a.length;
}));
Array.prototype.concat.apply is used to join the child arrays together.
You could do this quite neatly with underscore:
_.sortBy([a,b,c,d], function(num) {
return num.length;
}).reverse().join(',').split(',');
Mine's more verbose but still seems to work; the idea in all first 3 answers is to put the arrays into an additional array, then do a custom sort of the arrays based on their length. A good if somewhat dated reference is at: http://www.javascriptkit.com/javatutors/arraysort.shtml
var arrays = [a, b, c, d];
var concatentation = [];
arrays.sort(function(x, y) {
return y.length - x.length;
});
for (var i=0, n=arrays.length; i<n; i++) {
concatentation = concatentation.concat(arrays[i]);
}
console.log(concatentation); //[2, 3, 4, 5, 7, 8, 1, 6]