Outputting same value for two separate sorting functions - javascript

Hey doing drills on sorting and I found something that I don't fully understand.
let numbers = [1,3,2,5,4];
let sortedHighesttoLowest = numbers.sort((a, b)=> b-a);
let sortedLowesttoHighest = numbers.sort((a, b)=> a-b);
console.log(sortedHighesttoLowest);
console.log(sortedLowesttoHighest);
output:
[ 1, 2, 3, 4, 5 ]
[ 1, 2, 3, 4, 5 ]
how come this outputs only the last function's value twice even though I assigned them to two separate variable?

Arrays are passed by reference. So when you assign to your variable a sorted array and then you sort again, the first variable will also be affected. You can use spread operator to avoid this.
let numbers = [1,3,2,5,4];
let sortedHighesttoLowest = [...numbers.sort((a, b)=> b-a)];
let sortedLowesttoHighest = [...numbers.sort((a, b)=> a-b)];
console.log(sortedHighesttoLowest);
console.log(sortedLowesttoHighest);
//output:
//[ 1, 2, 3, 4, 5 ]
//[ 1, 2, 3, 4, 5 ]

The comparator function works little different than some traditional languages that you might be used to.
In js, the return value of comparator is -1, 0 and 1. Although in lot of cases you can get away with using - minus operator.
Having said that, you're passing array as reference here which is causing the problem.
Try running this:
let numbers = [1,3,2,5,4];
let sortedHighesttoLowest = numbers.sort((a, b)=> a - b);
console.log(sortedHighesttoLowest);
let sortedLowesttoHighest = numbers.sort((a, b)=> b - a);
console.log(sortedLowesttoHighest);
Additionally I'd encourage you to go through here as well

Related

JS - How is .filter working with this callback?

I'm new to Javascript and am currently going through the basics of callback functions and am having difficulty understanding why the code below returns an array of odds:
Code:
let numbers = [1, 2, 4, 7, 3, 5, 6];
function isOddNumber(number) {
return number % 2;
}
const oddNumbers = numbers.filter(isOddNumber);
console.log(oddNumbers); // [ 1, 7, 3, 5 ]
I see that the .filter is calling isOddNumber but I'm not sure how isOddNumber is passing or failing the values in the array. Is the return number % 2 pushing a 1 or 0 back to .filter and interpreting as truthy or falsy?
Any help here would be greatly appreciated!
#pilchard:
filter() passes each element to the provided isOddNumber callback, which in turn returns the remainder after dividing by 2 (either 0 or 1), which is evaluated as a boolean by the filter.

Calculate the mathematical difference of each element between two arrays

Given two array of same length, return an array containing the mathematical difference of each element between two arrays.
Example:
a = [3, 4, 7]
b = [3, 9, 10 ]
results: c = [(3-3), (9-4), (10,7)] so that c = [0, 5 3]
let difference = []
function calculateDifferenceArray(data_one, data_two){
let i = 0
for (i in data_duplicates) {
difference.push(data_two[i]-data_one[i])
}
console.log(difference)
return difference
}
calculateDifferenceArray((b, a))
It does work.
I am wondering if there is a more elegant way to achieve the same
Use map as following:
const a = [3, 4, 7]
const b = [3, 9, 10]
const c = b.map((e, i) => e - a[i])
// [0, 5, 3]
for-in isn't a good tool for looping through arrays (more in my answer here).
"More elegant" is subjective, but it can be more concise and, to my eyes, clear if you use map:
function calculateDifferenceArray(data_one, data_two){
return data_one.map((v1, index) => data_two[index] - v1)
}
calculateDifferenceArray(b, a) // < Note just one set of () here
Live Example:
const a = [3, 4, 7];
const b = [3, 9, 10 ];
function calculateDifferenceArray(data_one, data_two){
return data_one.map((v1, index) => v1 - data_two[index]);
}
console.log(calculateDifferenceArray(b, a));
or if you prefer it slightly more verbose for debugging et. al.:
function calculateDifferenceArray(data_one, data_two){
return data_one.map((v1, index) => {
const v2 = data_two[index]
return v1 - v2
})
}
calculateDifferenceArray(b, a)
A couple of notes on the version of this in the question:
It seems to loop over something (data_duplicates?) unrelated to the two arrays passed into the method.
It pushes to an array declared outside the function. That means if you call the function twice, it'll push the second set of values into the array but leave the first set of values there. That declaration and initialization should be inside the function, not outside it.
You had two sets of () in the calculateDifferenceArray call. That meant you only passed one argument to the function, because the inner () wrapped an expression with the comma operator, which takes its second operand as its result.
You had the order of the subtraction operation backward.
You could use higher order array method map. It would work something like this:
let a = [2,3,4];
let b = [3,5,7];
let difference = a.map((n,i)=>n-b[i]);
console.log(difference);
you can read more about map here

Javascript const is changeable?

I'm trying to delete max value from arMin and min value from arMax, but arr (is a const!) changes too! I don't know why. I am using Google Chrome version 65.0.3325.181.
'arr' is only one time declared and it shouldn't do nothing with that. I can't understand that. Tried with delete, but it's turning numbers into 'empty', but works the same and changes const too!
It's my first post, so if I do something wrong please forgive me.
const arr = [1, 2, 3, 4, 5];
let arMin = arr;
let arMax = arr;
let min = arMin.indexOf(Math.min.apply(null, arMin));
let max = arMax.indexOf(Math.max.apply(null, arMax));
arMin.splice(max, 1);
arMax.splice(min, 1);
console.log(arMin); // [2,3,4]
console.log(arMax); // [2,3,4]
console.log(arr); // [2,3,4]
The value of arr is a reference to an array.
You cannot change that. It will always be a reference to that array.
Arrays are mutable though, so you can change values in the array. const won't prevent that.
If you want arMin and arMax to be different arrays, then you need to make a copy of the array and not just copy the value of arr (which is a reference to that array).
const makes the reference constant, not the value.
You can't make arr point to something else, but you can change its values.
Note: other languages, Dart comes to mind, have the ability of specifying constant values. That's not the case of JavaScript.
When you make an array const then you can not change the reference
const arr = [1,2,3]
arr = [4,5,6] \\ Throws errors; You can not change const reference
arr[1] = 6; \\ Works fine. You are not changing the const reference. You are just mutating the array.
const x = 5; \\ Here constant is the value
x = x + 1; \\ Error. You can not change the constant value;
As a constant, you can't reassign its value, in this case, it contains the reference to the array.
But the array itself is not immutable.
An example would be:
const arr = [0,1,2,3,4,5];
arr = 'foo' // You cannot do that
arr.push(6) // That works fine. result: [0,1,2,3,4,5,6]
To complete previous answer, to make an exact copy of array instead of copying reference, you should do something like this :
const arr = [1, 2, 3, 4, 5];
let arMin = [...arr]; // We use spread operator to create new array from original one.
let arMax = [...arr];
let min = arMin.indexOf(Math.min.apply(null, arMin));
let max = arMax.indexOf(Math.max.apply(null, arMax));
arMin.splice(max, 1);
arMax.splice(min, 1);
console.log(arMin); // [1, 2, 3, 4]
console.log(arMax); // [2, 3, 4, 5]
console.log(arr); // [1, 2, 3, 4, 5]
--- EDIT 1 ---
i use TypeScript synthax to illustrate type
const arr = [1, 2, 3, 4, 5];
arr.push(6); // Is allow.
const object: {id: number, title: string} = {id: 1, title: 'Yanis'};
object.id = 2; // Is allow.
const myString: string = 'yanis';
myString = 'Jackob'; // Not allow.

Why A and B are equal after sort()?

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

Javascript arrays of Objects; Subtract one from another

Put simply, I want to subtract one array from another.
The arrays are arrays of objects. I understand I can cycle through one array and on each item, comparing values in the other array, but that just seems a little messy.
Thanks for the help, hopefully this question isnt too basic, I have tried googling it with no luck :(
EDIT:
The Objects in the Arrays I wish to remove will have identical values but are NOT the same object (thanks #patrick dw). I am looking to completely remove the subset from the initial array.
This answer is copied from https://stackoverflow.com/a/53092728/7173655, extended with a comment and a solution with objects.
The code filters array A. All values included in B are removed from A.
const A = [1, 4, 3, 2]
const B = [0, 2, 1, 2]
console.log(A.filter(n => !B.includes(n)))
The same with objects:
const A = [{id:1}, {id:4}, {id:3}, {id:2}]
const B = [{id:0}, {id:2}, {id:1}, {id:2}]
console.log(A.filter(a => !B.map(b=>b.id).includes(a.id)))
http://phpjs.org/functions/index
There is no built-in method to do this in JavaScript. If you look at this site there are a lot of functions for arrays with similar syntax to PHP.
http://www.jslab.dk/library/Array
This site has some js functions on "sets"
I think you need the diff function.
It should remove all values from list a, which are present in list b keeping their order.
let a = [0, 2, 5, 6, 1];
let b = [2, 6, 2, 5, 0];
function arrayDiff() {
for (i of b) {
for (j of a) {
if (i === j) {
a.splice(a.indexOf(j), 1);
}
}
}
return a;
}

Categories