Enumerable Functions Specifically the `.reduce()` function in JavaScript - javascript

I have this code here that I've set up:
var numbers = [1,2,3,4,5,6,7,8,9,2,3,4,5,6,1,2,3,4,5,6,7,8,8,4,3,2];
var greaterThan3 = numbers.filter (item => item >= 3);
console.log(greaterThan3);
greaterThan3.reduce((item, amount) => item + amount);
but it only gives me this:
[3, 4, 5, 6, 7, 8, 9, 3, 4, 5, 6, 3, 4, 5, 6, 7, 8, 8, 4, 3]
And, I know it probably has something to do with how I set up the .reduce() line. I'm trying to get the numbers greater than or equal to 3 to add up to one number. I'm assuming I have to define total and amount but I'm not sure. Just learning this chapter from Bloc so excuse the probably dumb question.

Related

why it is returning only false? Luhn algorithm

What's wrong with my code? It should return true for this array. The invalid one should return false.
Please explain it to me because i'm just started with JS
//arrays :
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const validateCred = Array => {
let cardNum = 0
let reverseArray = Array.reverse()
for (let i = 0; i < reverseArray.length; i++){
let newVar = reverseArray[i]
if (i%2 !== 0){
newVar = reverseArray[i] * 2
if (newVar > 9){
newVar = newVar[i] - 9;
cardNum += newVar
} else {
cardNum += newVar
}
} else {
cardNum += reverseArray[i]
}
}
return(cardNum%10 === 0 ? true : false)
}
console.log(validateCred(valid1))
As you figured out and noted in the comments, this is not going to go well when newVar is a number:
newVar = newVar[i] - 9;
And as Pointy, um, pointed out, Array is a terrible name for a variable, shadowing an important constructor function. More than that, there is a strong convention in JS that InitialCapital variable names are reserved for constructor functions. I would suggest a name that describes what it's for, not its type. Perhaps "creditCard" would be useful, or, depending on your tolerance for short abbreviations, "cc".
But there's another, more subtle, problem with this code. It alters its input:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
console .log (validateCred (valid1)) //=> true
console .log (valid1) //=> [8, 0, 8, 6, 1, 0, 8, 0, 9, 7, 7, 6, 9, 3, 5, 4]
In a real application, this could cause you all sorts of problems, and maybe far away from this section, always frustrating.
It's easy enough to fix. Just clone the array before reversing it. There are many ways to do it (using myVariable.slice() or myVariable.concat(), for instance.) My preference these days is to spread it into a new array: [...myVariable].
In my answer to another Luhn's Algorithm question, I developed what I think of as an elegant version of this algorithm. If you're new to JS, this may use some features you're not familiar with, but I find it clear and useful. This is a slightly improved version:
const luhn = (ds) => ([...ds]
.filter(d => /^\d$/ .test (d))
.reverse ()
.map (Number)
.map ((d, i) => i % 2 == 1 ? (2 * d > 9 ? 2 * d - 9 : 2 * d) : d)
.reduce ((a, b) => a + b, 0)
) % 10 == 0
It's the same algorithm, just expressed a little more concisely. Between the spreading of the initial value and the filter call (removing non-digits), it allows us to pass various input formats:
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = "4539677908016808"
const valid3 = "4539-6779-0801-6808"
const valid4 = "4539 6779 0801 6808"

does python have an equivalent to javascript's every and some method?

I was trying to search the docs for a method similar but I was only able to find pythons all() and any(). But that's not the same because it just checks if the val is truthy instead of creating your own condition like in js' every and some method.
i.e
// return true if all vals are greater than 1
const arr1 = [2, 3, 6, 10, 4, 23];
console.log(arr1.every(val => val > 1)); // true
// return true if any val is greater than 20
const arr2 = [2, 3, 6, 10, 4, 23];
console.log(arr2.some(val => val > 20)); // true
Is there a similar method that can do this in python?
Just combine it with a mapping construct, in this case, you would typically use a generator expression:
arr1 = [2, 3, 6, 10, 4, 23]
print(all(val > 1 for val in arr1))
arr2 = [2, 3, 6, 10, 4, 23]
print(any(val > 20 for val in arr2))
Generator comprehensions are like list comprehensions, except they create a generator not a list. You could have used a list comprehension, but that would create an unecessary intermediate list. The generator expression will be constant space instead of linear space. See this accepted answer to another question if you want to learn more about these related constructs
Alternatively, albeit I would say less idiomatically, you can use map:
arr1 = [2, 3, 6, 10, 4, 23]
print(all(map(lambda val: val > 1, arr1)))
arr2 = [2, 3, 6, 10, 4, 23]
print(any(map(lambda val: val > 20, arr2)))
Yes, Python has it.
numbers = [1, 2, 3, 4, 5]
all_are_one = all(elem == 1 for elem in numbers)
some_are_one = any(elem == 1 for elem in numbers)

Converting String to Number in Javascript

I'm stuck in small problem where I'm trying to convert String to number but that String number is huge due to which it is not properly converting to number type.
str = "6145390195186705543"
num = Number(str)
digits = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3]
let str = String(Number(digits.join(''))+1).split('')
after performing above operation the value of num is 6145390195186705000 which is not what I was expecting. It should be 6145390195186705543.
It would be very helpful if someone can explain this and tell if there is any alternative way.
I have tried parseInt() and '+' as well but nothing is working.
If you want to increment an array of integer values, you can join the digits and pass it to the BigInt constructor. After it is a BigInt, you can add 1n. Once you have added the value, you can stringify the value and split it. Lastly, you can map each digit back into an integer.
const digits = [6, 1, 4, 5, 3, 9, 0, 1, 9, 5, 1, 8, 6, 7, 0, 5, 5, 4, 3];
const str = (BigInt(digits.join('')) + 1n).toString().split('').map(digit => +digit);
console.log(JSON.stringify(str)); // [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,4]
Here is the code above, modified into a function:
const numArrayAdd = (bigIntSource, bigIntAmount) =>
(BigInt(bigIntSource.join('')) + bigIntAmount)
.toString().split('').map(digit => +digit);
const digits = [6, 1, 4, 5, 3, 9, 0, 1, 9, 5, 1, 8, 6, 7, 0, 5, 5, 4, 3];
const str = numArrayAdd(digits, 1n);
console.log(JSON.stringify(str)); // [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,4]
you can add just a + right before that variable
here is a good example about that
https://youtu.be/Vdk18Du3AVI?t=61

Finding and removing matching and corresponding values in an array

Here's a sample of the problem I'm having in JavaScript:
first array [1, 2, 3, 4, 5, 6, 7]
second array [7, 8, 9, 4, 2, 5, 7]
In this case, I need to be able to find and eliminate "4" and "7" from both arrays, eliminating both. This is based on their location and matching value.
I haven't been able to find anything other than eliminating matching values. In this case, however, the values must be in the same place and also be matching.
I've tried this so far:
function findCommonElements3(array1, array2) {
return arr1.some(item => arr2.includes(item))
}
it looks like it only looks for matching elements, whereas I need to find matching corresponding elements and then remove them.
As mentioned in the comments, you may use the splice method to remove one or more elements of an array in JavaScript.
First of all I would store the indexes of the elements I should remove looping the array as so:
const array1 = [1, 2, 3, 4, 5, 6, 7];
const array2 = [7, 8, 9, 4, 2, 5, 7];
//Indexes of same elements
var sameIndexes = [];
function findSameIndexes(element, index) {
if (array1[index] == array2[index]) {
sameIndexes.push(index);
}
}
array1.forEach(findSameIndexes);
Calling console.log(sameIndexes) should give this result:
Array [3, 6]
The problem is that if you loop again the array and remove the elements in that order, the indexes would not correspond to the elements anymore.
For example if you remove the 3rd element, the number 7 wouldn't be at index 6 anymore, to solve this issue I'd use the reverse method so you won't lose track of the indexes
// A simple function to remove the elements in both arrays
function removeElements(index) {
array1.splice(index,1);
array2.splice(index,1);
}
sameIndexes.reverse().forEach(removeElements);
And the final results would be
Array [1, 2, 3, 5, 6]
Array [7, 8, 9, 2, 5]
Which hopefully is what you were looking for, of course there are better ways to write it down, but maybe this will help you find a solution.
You could just use a for loop and use index. something like this
const firstarray = [1, 2, 3, 4, 5, 6, 7]
const secondarray = [7, 8, 9, 4, 2, 5, 7]
for (let i = 0; i <= firstarray.length - 1; i++) {
if (firstarray[i] === secondarray[i]) {
console.log(`found ${firstarray[i]} at index ${i}`);
firstarray.splice(i, 1);
secondarray.splice(i, 1);
}
}
console.log(firstarray, secondarray);
const excludeCommon = (ar1, ar2) => {
const both = [...ar1, ...ar2].filter((v, i, ar) => v !== ar[i + (2 * (i < ar1.length) - 1) * ar1.length]);
return [both.slice(0, both.length / 2), both.slice(both.length / 2)];
}
console.log(excludeCommon([1, 2, 3, 4, 5, 6, 7], [7, 8, 9, 4, 2, 5, 7]));

Get the N elements from array based on the position

I want a function that returns the sub array which takes a position & the no. of elements I want. I think there may be some algorithm to find the pivot point or something & from that I can get the sub array, but I totally forgot it.
Example: a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I want 6 elements
if position = 0, then I want [1, 2, 3, 4, 5, 6]
if position = 1, then [1, 2, 3, 4, 5, 6]
if position = 2, then [1, 2, 3, 4, 5, 6]
if position = 3, then [1, 2, 3, 4, 5, 6]
if position = 4, then [2, 3, 4, 5, 6, 7]
if position = 5, then [3, 4, 5, 6, 7, 8]
if position = 6, then [4, 5, 6, 7, 8, 9]
if position = 7, then [5, 6, 7, 8, 9, 10]
if position = 8, then [5, 6, 7, 8, 9, 10]
if position = 9, then [5, 6, 7, 8, 9, 10]
simply get the middle of N elements based on the position I pass.
I can write up my own loop which will contain multiple if-else conditions to get it done. But I feel there may be some easy way to do it.
I didnt include my incomplete code snippet because I strongly feel there must be some algorithm to do this.
What you want is : Array.prototype.slice(...)
It's neatly documented here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
var n = 6;
var start = Math.max(0, Math.min(Math.floor(position-n/2), a.length-n));
return a.slice(start, start+n);
Simple way:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
function getSubArray(idx, _length, _array) {
return _array.slice(idx, idx + _length);
}
var subArray = getSubArray(3, 6, a);
You could use an offset for the postion and get the the start value first for slicing.
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
n = 6,
i,
start;
for (i = 1; i < 12; i++) {
start = Math.max(Math.min(i - n / 2, a.length - n), 0);
console.log(i, ': ', a.slice(start, start + n).join());
}
Your only need is to check if you are not gonna check a pos that doesn't exist. Like :
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var n = 6; // Number of result you want
var x = 8; // Pos you want
// If you gonna exceed your length, we got only the n last element
if((x+(n/2)) > a.length) {
console.log(a.slice(a.length-n));
// Otherwise, if under 0, we got the n first
} else
if((x-(n/2)) < 0) { console.log(a.slice(0,n) );
// Default case
} else {
console.log(a.slice((x-(n/2)),(x+(n/2))));
}
This is not the smartest way, but he can give you some hint. I used the slice as other mentionned to avoid a lot of if, but you should do GENERIC test.
Something like this :
a = [1,2,3,4,5,6,7,8,9,10];
n = 6;
function split(position) {
var start = Math.min(Math.max(position - Math.floor(n/2), 0), a.length - n);
var stop = Math.min(start+n, a.length);
return a.slice(start, stop);
}
No need for the Math object at all. You may simply do as follows;
function getArr(a,n,d){
n = n - 4 < 0 ? 0
: a.length - d > n - 4 ? n - 3
: a.length - d;
return a.slice(n,n + d);
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
diff = 6;
for (var i = 0; i < 10; i ++) console.log(JSON.stringify(getArr(arr,i,diff)));
no need of if-else you can use arr[position] to arr[8]. have you got
function getArr(arr,position,requiredNumbers){
return arr.slice(position, position+requiredNumbers);
}

Categories