What is the shortest way to negate all elements in a javascript array, with reasonable efficiency?
For example, the solution would convert [0, 18, -1, -2, 1, 3] to [0, -18, 1, 2, -1, -3]
The solution does not need to handle any values that are NaN/undefined/null, because the array I need this for does not contain any of those values.
Here is what I normally do (with array array):
for(var i = 0; i < array.length; i++) {
array[i]*=-1
}
The problem is that I need to invert this array in several places, so don't want to reuse large code.
Thanks
That would be array.map returning the negative of each value. Adding in arrow function for an even shorter syntax.
var negatedArray = array.map(value => -value);
negate all elements in a javascript array
I think you are referring to negate only the positive number.
var _myArray = [0, 18, -1, -2, 1, 3]
var _invArray = [];
_myArray.forEach(function(item){
item >0 ?(_invArray.push(item*(-1))) :(_invArray.push(item))
})
console.log(_invArray);
JSFIDDLE
Related
I trying to came up algorithm in js for sorting from closest to farthest by given number, for example (number: 5.6666, array: [-1, 9, 4, 10, 11, 0]) should return [4, 9, 10, 0, 11, -1].Any idea how approach to the problem? A little gotcha actually my array is array of objects and I need sort by certain key in object. In docs said, that should use array.sort() with compare function, but I don't understand how implement this function.
The sort() function of Array can take a function:
[1,2,3].sort((a, b) => /* do something */)
Each time, you should return a value. A negative number will mean a comes before b. A positive number means b comes before a. 0 means they are equal.
If you want distance to the number, you want the absolute value, with Math.abs(). Assuming the key on the object is value, you can put it all together:
const target = 5;
const values = [{ value: -100 }, { value: 1 }, { value: 4 }, { value: 6 }, { value: 10 }];
const result = values.sort(({ value: a }, { value: b }) =>
Math.abs(target - a) - Math.abs(target - b));
console.log(result);
I used some ES6 destructuring to make it a bit cleaner by pulling the value out in the parameters.
If you wanted to just have the values remaining (instead of the objects), you can either use map() after the fact (or before).
Note, in the case of 2 numbers being equidistant from the target (in my example, 4 and 6 are both 1 away from the target), you can't guarantee which will come first. If it matters to you, you'll want to add some extra logic to hand that scenario.
Using sort, you can check each of their distances from your number.
var num = 5.666
var arr = [-1, 9, 4, 10, 11, 0]
arr.sort(function(a, b){
return Math.abs(num-a) - Math.abs(num-b);
});
console.log(arr)
Use array.sort and get the difference of each number from the input value given
var inputArray = [-1, 9, 4, 10, 11, 0],
input = 5;
var closest = inputArray.sort(function(a, b){
return Math.abs(input-a) - Math.abs(input-b);
});
console.log(closest);
I'm trying to understand the following solution for finding the largest adjacent product in any given array.
Example:
For inputArray = [3, 6, -2, -5, 7, 3], the output should be
adjacentElementsProduct(inputArray) = 21.
7 and 3 produce the largest product.
Possible solution in JS:
function adjacentElementsProduct(arr) {
return Math.max(...arr.slice(1).map((x,i)=>[x*arr[i]]))
}
I am having a hard time understanding two things:
What do the three dots exactly do and how does this get passed into the function? Is there any way to write this in a more understandable way? I know that is the "spread syntax" feature in ES6, but still don't understand completely.
Why do we insert "1" as argument to slice? My first though was to input "0", because we want to start at the start, then loop through everything, and see which adjacent product is the largest.
I'd appreciate any advice, links and explanations.
Thanks.
Cheers!
1. What do the three dots exactly do and how does this get passed into the function? Is there any way to write this in a more understandable way? I know that is some kind of "spread" feature in ES6, but still don't understand completely.
The Math#max needs a list of numbers as parameters, and map produces an array. The spread syntax is used to convert an array to be expanded to a list of parameters.
const arr = [1, 2, 3];
console.log('max on array', Math.max(arr));
console.log('max on list of parameters', Math.max(...arr));
In this case you can use Function#apply to convert the array to a list of parameters. I find it less readable, however.
const arr = [1, 2, 3];
console.log(Math.max.apply(Math, arr));
2. Why do we insert "1" as argument to slice? My first though was to input "0", because we want to start at the start, then loop through everything, and see which adjacent product is the largest.
Lets break down the iteration order of the 2 arrays.
[3, 6, -2, -5, 7, 3] // inputArray
[6, -2, -5, 7, 3] // inputArray.slice(1)
Now on each iteration of inputArray.slice(1):
x: 6, i = 0, arr[0] = 3
x: -2, i = 1, arr[1] = 6
x: -5, i = 2, arr[2] = -2
Since the inputArray.slice(1) array starts from the 2nd element of the inputArray, the index (i) points to the 1st element of the inputArray. And the result is an array of products of 2 adjacent numbers.
var biggestProduct = inputArray[0] * inputArray[1];
for (i=0; i<inputArray.length-1 ; ++i)
{
console.log(biggestProduct)
if ((inputArray[i] * inputArray[i+1] ) > biggestProduct)
{
biggestProduct = inputArray[i] * inputArray[i+1]
}
}
return biggestProduct;
Note: I've declared a variable that consists of 2 input arrays with index number then starts a for loop that indicates input array with his index number, so by that he will go throw all the index number of the array (one of them raised by one so that they won't be at the same value). and at the end of the code, you have the if statement.
You may simply do as follows;
function getNeigboringMaxProduct([x,...xs], r = -Infinity){
var p = x * xs[0];
return xs.length ? getNeigboringMaxProduct(xs, p > r ? p : r)
: r;
}
var arr = [3, 6, -2, -5, 7, 3],
res = getNeigboringMaxProduct(arr);
console.log(res);
Please help, I've been looking for an answer for far too long.
I'm trying to create an array using push method to insert the numbers
0 to 10 into positions 0 through 10 of the numbers array you just initialized above.
I did this:
var numbers = [];
for(var i = 0; i < 10; i++) {
numbers.push(i);
console.log(numbers);
And got this result, which I think is correct but not 100% sure:
[ 0 ]
[ 0, 1 ]
[ 0, 1, 2 ]
[ 0, 1, 2, 3 ]
[ 0, 1, 2, 3, 4 ]
[ 0, 1, 2, 3, 4, 5 ]
[ 0, 1, 2, 3, 4, 5, 6 ]
[ 0, 1, 2, 3, 4, 5, 6, 7 ]
[ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
0
Then I am to test the array push method by printing the sum of the values at
position 3 and 6 of the array (use the console.log() function to print to the console).
The outputted value should be 9.
I am so stuck on this point and cannot find a sample anywhere of how to accomplish this. I thought it might be something like:
console.log(numbers(sum[3, 6]);
If you want to have a sum() function, then try the following:
function sum(x, y) {
return x + y;
}
console.log(sum(numbers[3], numbers[6]));
Here's a Fiddle: https://jsfiddle.net/7181h1ok/
To sum the values of two indices of an array, you use the + addition operator in the following fashion:
var numbers = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
var sum = numbers[3] + numbers[6]; //adds the value in index 3 of the numbers array to the value in index 6 of the numbers array.
console.log(sum); //prints the sum to the console.
As a note, if you are unfamiliar with JavaScript and/or its operators, there's useful documentation at w3schools that can get you started.
First, let's convert your code to a little bit better style:
const numbers = [];
for (let i = 0; i < 10; i++) {
numbers.push(i);
console.log(numbers);
}
Note: I made numbers a const instead of a var, since you don't change it. I also made i a let binding instead of a var. In general, var is a legacy and should never be used. Use const instead if at all possible, otherwise use let.
Also, I inserted a space after the for keyword. It is generally recommended to separate the parentheses which enclose the header of a control structure keyword (if, while, for, etc.) with a space, to make it visually distinct from the parentheses for the argument list of a function call, which has no space.
Secondly: Your result is not correct. (Hint: how many numbers are the numbers 0 to 10?) It should include the numbers 0 to 10, but it only includes the numbers 0 to 9. You have what is generally called an off-by-one-error. These errors are very common when dealing with trying to manage loop indices manually. This is the fix:
const numbers = [];
for (let i = 0; i <= 10; i++) {
// ↑
numbers.push(i);
console.log(numbers);
}
Most modern programming languages have better alternatives than dealing with loop indices manually in the form of higher-level abstractions such as iterators, maps, and folds. Unfortunately, ECMAScript doesn't have a Range datatype, otherwise this could simply be expressed as converting a Range to an Array.
If ECMAScript did have a Range datatype, it could for example look like one of these:
const numbers = Range(0, 10).toArray()
const numbers = Array.from(Range(0, 10))
Here is an alternative for creating the numbers Array that doesn't involve manually managing loop indices, but still requires knowing that 0 to 10 are 11 numbers:
const numbers = Array.from({length: 11}, (_, i) => i)
If you want to add the numbers at indices 3 and 6, you can simply dereference indices 3 and 6 and add the results:
console.log(numbers[3] + numbers[6])
In the comments, you asked how you would add up all numbers in the Array. Combining the elements of a collection using a binary operator is called a fold or reduce, and ECMAScript supports it out-of-the-box:
console.log(numbers.reduce((acc, el) => acc + el));
Note how there is no explicit loop, thus no explicit management of loop indices. It is simply impossible to make an off-by-one-error here.
It will be: console.log((+numbers[3]) + (+numbers[6]));
Typically, it should be console.log(numbers[3] + numbers[6]); but there's sometimes a issue that results in 36 instead of 9. The extra + signs tell javascript that it is a number.
NOTE: Remember that the first number is numbers[0]. The array starts with 0!
I know how to compare values in two arrays using 2 for loops however I was looking for something a bit more sophisticated like creating an iterator to iterate through one of the arrays and passing the other array to mapmethod . Is that even possible?
I'm doing a small program for class which takes an array and x arguments and I currently have extracted the values from the arguments.
function dest(arr){
var args =[];
for(var i = 1; i < arguments.length; i++){
args.push(arguments[i]);
}
return args;
}
console.log(dest([1, 2, 3, 4], 4, 4));
Now, how could I do the iterator part to compare the values inside arr and args? Thanks for the help.
The result should be the results that match from both arr and args.
You can use the built in filter method
var arr = [2, 3, 4, 5, 6];
var args = [3, 5, 6, 7];
var result = arr.filter(function(element) {
return args.indexOf(element) > -1;
});
This will filter out all the elements out that are not present in both arrays. The result is a new array that contains only the matching values [3, 5, 6].
I'm trying to write a for loop that finds the largest element in the array and log that element to the console. I got this so far but it doesn't work. Can anyone help?
var array = [3, 6, 2, 56, 32, 5, 89, 32];
var largest = 0;
for (var i = 0; 0 < 100; i++ ) {
if (array[i] > largest) {
largest = array[i]);
}
}
console.log(largest);
like #elclanrs said, you want to use the built-in Math.max function. You could simply write:
var array = [3, 6, 2, 56, 32, 5, 89, 32];
var largest = Math.max.apply(null, array);
More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
Well, #elclanrs said it in comments already, however...
You can use Math.max, which takes a various number of numbers as arguments. However Math.max doesn't take an array as argument, so we use Function.prototype.apply to pass every element in the array as individual arguments.
Math.max.apply(Math, [3, 6, 2, 56, 32, 5, 89, 32]);
Note: The first argument of apply is the object to which the context object will be set when executing the function. In other words, it specifies the value of this. In this case it could be null and it wouldn't make any difference.
As for your initial code, you have some syntax errors and you should lint your code.
Change the for-loop to:
for (var i = 0; i < array.length; i++ ) {
#plalx is right, there's one more issue, in the line:
largest = array[i]);
There's an unnecessary closing bracket ")" which should be removed.
Apply these two changes - and the code will work.