//Конкурсный проект: проверка кредитных карт//Challenge Project: Credit Card Checker// Мое решение на gist.github://
https://gist.github.com/mtapirina/41c32800b7a452f516b7090933dc3e58//https://gist.github.com/codecademydev/db9f766146d5000a2dcf526e247b879a// Все действительные номера кредитных картconst valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = [5, 5, 3, 5, 7, 6, 6, 7, 6, 8, 7, 5, 1, 4, 3, 9];
const valid3 = [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6];
const valid4 = [6, 0, 1, 1, 1, 4, 4, 3, 4, 0, 6, 8, 2, 9, 0, 5];
const valid5 = [4, 5, 3, 9, 4, 0, 4, 9, 6, 7, 8, 6, 9, 6, 6, 6];
// Все недействительные номера кредитных картconst invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const invalid2 = [5, 7, 9, 5, 5, 9, 3, 3, 9, 2, 1, 3, 4, 6, 4, 3];
const invalid3 = [3, 7, 5, 7, 9, 6, 0, 8, 4, 4, 5, 9, 9, 1, 4];
const invalid4 = [6, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5];
const invalid5 = [5, 3, 8, 2, 0, 1, 9, 7, 7, 2, 8, 8, 3, 8, 5, 4];
//Может быть действительным или недействительнымconst mystery1 = [3, 4, 4, 8, 0, 1, 9, 6, 8, 3, 0, 5, 4, 1, 4];
const mystery2 = [5, 4, 6, 6, 1, 0, 0, 8, 6, 1, 6, 2, 0, 2, 3, 9];
const mystery3 = [6, 0, 1, 1, 3, 7, 7, 0, 2, 0, 9, 6, 2, 6, 5, 6, 2, 0, 3];
const mystery4 = [4, 9, 2, 9, 8, 7, 7, 1, 6, 9, 2, 1, 7, 0, 9, 3];
const mystery5 = [4, 9, 1, 3, 5, 4, 0, 4, 6, 3, 0, 7, 2, 5, 2, 3];
//Массив из всех массивов вышеconst batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2,invalid3, invalid4, invalid5, mystery1, mystery2, mystery3, mystery4,mystery5];
//Мои массивы для тестированияconst test = [4, 5, 3, 9, 6, 8, 9, 8, 8, 7, 7, 0, 5, 7, 9, 8];
const test1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const test2 = [6, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5];
//неверное первое число — 9 — для проверки «Компания не найдена»const test3 = [9, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5];
//неверный пакетный массив (массив из массивов с неверными номерами картconst batchInv = [ invalid1, test3, invalid2,invalid3, invalid4, invalid5];
/*Создайте функцию validateCred() , которая имеет параметр массива. Цель validateCred() — вернуть true, если массив содержит цифры действительного номера кредитной карты, и false, если он недействителен. Эта функция НЕ должна изменять значения исходного массива.*/function validateCred(array){
/*шаг 1 — Удалить последний элемент из массива,
(но помните: вы не хотите изменять исходный массив!):*/const arr = array.slice();//copy of array
//console.log((array === arr) + ' copy of array');let checkDigit = arr.pop();//Remove the last element from the array
//шаг 2 — Переверните массив (теперь без последней цифры):const reverseArray = arr.map((_, index) =>
arr[arr.length - 1 - index]);
/*Шаг 3. Умножьте цифры в нечетных позициях.
(например, первая цифра, третья, пятая и т. д.) на 2.
Если полученное число больше 9, вычтите 9 из числа:*/let sum = 0;
for (let i = 0; i < reverseArray.length; i++){
let x = reverseArray
; // currentIndex
if( i % 2 === 0 ){
x *= 2;
x > 9?x -= 9:x;
}
sum += x;
}
/*Шаг 4. Сложите все числа в массиве, а также пропущенную цифру из шага 1. Если сумма по модулю 10 равна 0 , то массив содержит допустимое число: */
return (sum + checkDigit) % 10 === 0? true : false;
};
/* Создайте еще одну функцию findInvalidCards() , имеющую один параметр для вложенного массива номеров кредитных карт.
Роль findInvalidCards() — проверить во вложенном массиве недопустимые числа и вернуть другой вложенный массив недействительных карточек.
*/
function findInvalidCards(array){
const invalidCards = array.filter((element) => !validateCred(element));
return invalidCards;
};
/*5
Создайте функцию idInvalidCardCompanies() , которая имеет один параметр для вложенного массива недопустимых чисел и возвращает массив компаний.
В настоящее время существует 4 принятые компании, каждая из которых имеет уникальные первые цифры.
3 Amex (American Express)
4 Visa
5 Mastercard
6 Discover
Если номер не начинается ни с одной из перечисленных цифр, распечатайте сообщение типа: «Компания не найдена».
idInvalidCardCompanies() должен возвращать массив компаний, которые разослали карты с недопустимыми номерами. Этот массив НЕ должен содержать дубликатов, т. е. даже если есть две недействительные карты Visa, Visa должна появиться в массиве только один раз.
*/
function idInvalidCardCompanies(array){
const pushArr = [];
array.forEach((el)=>{
//console.log(el[0])
switch(el[0]){
case 3:
if(pushArr.indexOf('Amex (American Express)')=== - 1){
pushArr.push('Amex (American Express)');
}
break;
case 4:
if(pushArr.indexOf('Visa')=== - 1){
pushArr.push('Visa');
}
break;
case 5:
if(pushArr.indexOf('Mastercard')=== - 1){
pushArr.push('Mastercard');
}
break;
case 6:
if(pushArr.indexOf('Discover')=== - 1){
pushArr.push('Discover');
}
break;
default:
if(pushArr.indexOf('Company not found')=== - 1){
pushArr.push('Company not found');
}
break; };
})
return pushArr;
};
/*extra:
Чтобы проверить номера кредитных карт, создайте функцию, которая принимает строку и преобразует ее в массив чисел, подобный изначально предоставленным массивам.*/
function convertToNumbersArray (string){
//преобразовать строку => в массив символов
let x = Array.from(string);
console.log(x);
//новый массив чисел => преобразовать символы в числа
const toNumbersArray = x.map(el =>{
let toNum = parseInt(el);
return toNum;
});
//если элемент нового массива NaN?
const validNumbers = toNumbersArray.some(el=>
Number.isNaN(el));
//console.log(validNumbers);
//console.log(toNumbersArray);
if(!validNumbers){
return toNumbersArray;
}else{
return 'Wrong number of Credit Card. This function accepts only numbers!'
}
};
//Преобразовать недействительный номер кредитной карты в действительный
function convertToValidCard (array){
const arr = array.slice();// копия исходного массива
let lastDigit = arr.pop(); //удалим последнюю цифру из arr и сохраним ее в переменной lastDigit
//console.log(lastDigit);
//console.log(arr);
//применить обратный цикл к массиву arr (к копии урезанного номера кредитной карты)
let sum = 0;
for(let i = arr.length - 1; i >= 0; i--){
let x = arr;
if(i % 2 === 0){
x *= 2;
x > 9? x -= 9:x;
}
//console.log(x)
sum += x;
}
//console.log(sum + ' sum');
//console.log(lastDigit + ' - last digit');
let result = sum + lastDigit;
//console.log(result + ' - result');
if(result % 10 !== 0){
let y = Math.round(result/10)* 10;
//console.log(y + ' - result round 10%');
if(sum % 10 === 0){
lastDigit = 0;
}else{
lastDigit = y - sum;
}
//console.log(lastDigit + ' - last digit changed');
arr.push(lastDigit);
}else{
return 'This Credit Card is valid. Please insert invalid Credit Card number'
}
//console.log(arr);
return arr;
};
// test
//console.log('test2(invalid) convert to valid cc number');
//console.log(convertToValidCard(test2));
//console.log(validateCred(convertToValidCard(test2)));
//console.log('parse Int - new array of integers');
//console.log(convertToNumbersArray ('49161591k0658210'));
//console.log('batchInvalid - Company not found =>');
//console.log(idInvalidCardCompanies(batchInv));
//console.log('batch - id Invalid Card Companies =>');
//console.log(idInvalidCardCompanies(batch));
//console.log('batch - findInvalidCards( =>');
//console.log(findInvalidCards(batch));
//console.log('batchInvalid - findInvalidCards(6) =>');
//console.log(findInvalidCards(batchInv))
//console.log('test true - validateCred =>');
//console.log(validateCred(test));
//console.log(validateCred(test2));
//console.log(validateCred(valid1));
//console.log('test false - validateCred =>');
//console.log(validateCred(convertToNumbersArray ('3542403720469485746')));
//console.log(validateCred(invalid1));
//console.log('test mystery (false = 2, true = 3) - validateCred =>');
//console.log(validateCred( mystery5));
Возможно, все это можно сделать как то короче и красивее... Но я в принципе довольна и тому что у меня получилось.
Работает вроде бы правильно, по крайней мере мне ошибки удалось исправить и больше они не повторялись..
Вообще этот конкурс мне очень понравился! По ходу поиска решений узнала кое что новое.. Например как округлять до десятка ближайшего с помощью Math.round(var/10)* 10;
или о том, что копию - дубликат массива быстро и просто можно сделать так
const arr = array.slice(); и при проверке - это именно другой масив, а исходный останется не тронутым.
О проверке Number.isNaN() - существует ли число, или его нет (нет никакого значения) и т.д.