#javascript #arrays #data-structures #nested-lists #undefined-function
#javascript #массивы #структуры данных #вложенные списки #неопределенная-функция
Вопрос:
Я написал функцию, которая принимает оценку в качестве параметра и должна возвращать буквенную оценку. При написании кода необходимо соблюдать некоторые условия. ie: return 'A' if 25 < score <= 30
return 'B' if 20 < score <= 25
и так далее. Поэтому я хотел сделать это, опустив множество if-else's
. Поскольку я новичок в javascript, это все, что я мог придумать:
// This function takes Nested arrays and a single number,
// which checks its availability in
// the inside array and then return the index of the array
function my_index(arr, score) {
for (const [index, elem] of arr.entries()) {
if (elem.includes(score)) {
return index;
}
}
}
// function to get letter grade
function getGrade(score) {
let grade;
var gradeDict = {
'A': [26, 27, 28, 29, 30],
'B': [21, 22, 23, 24, 25],
'C': [16, 17, 18, 19, 20],
'D': [11, 12, 13, 14, 15],
'E': [6, 7, 8, 9, 10],
'F': [0, 1, 2, 3, 4, 5]
}
var keys = Object.keys(gradeDict);
var values = [Object.values(gradeDict)]
grade = keys[my_index(values, score)]
return grade;
}
Первая функция работает нормально. Возвращает индекс вложенного массива. Но основная функция getGrade
возвращается 'Undefined'
. Не могу придумать лучшего решения, чем это, чтобы уменьшить кучу уродливых if-else.
var question = {
'1st': 'Can anybody help me get this done?',
'2nd': 'Is there any better way to do this?'
}
Комментарии:
1. Попробуйте
value = Object.values(gradeDict)
, а неvalue = [Object.values(gradeDict)]
. Первый создает массив like[[[26, 27 28, 29, 30], ...]]
, второй — массив lke[[26, 27, 28, 29, 30], ...]
, что больше соответствуетmy_index
ожиданиям.2. Поскольку я разработал ‘my_index’ для вложенного списка, я подумал, что должен сделать его списком списка в ‘getGrade’. Теперь это работает, большое вам спасибо. И есть ли лучший способ добиться этого, кроме этого?
3. Любое решение, имеющее
[26, 27, 28, 29, 30]
etc., не является хорошим решением, имхо. Это диапазоны последовательных целых чисел, поэтому нет необходимости хранить их в виде списков. Один из способов понять, что это плохое решение, — увеличить размер проблемы — допустим, существует 26 классов (от А доЯ) или 1 миллион классов. Как бы в этом случае выглядело ваше решение с использованием списков? Это ваш ключ к пониманию того, что решение на основе списков — плохой выбор.4. Спасибо, что указали на это. Не могли бы вы показать лучшее решение? @jarmod
5.
ceil
Решение лучше, имо. Это намного проще и является лучшим обобщением.
Ответ №1:
Есть ли лучший способ написать это?
Я бы сделал:
function getLetterGrade(score) {
return ['F', 'F', 'E', 'D', 'C', 'B', 'A'][Math.ceil(score / 5)];
}
( F
встречается дважды, потому что больше баллов сопоставляется с F, чем с другими оценками)
Это может быть немного загадочно, но его легче настроить, если возможный результат когда-либо изменится.
Комментарии:
1. в нашей текущей ситуации оценка за каждую оценку соответствует 5 числам, за исключением ‘F’. таким образом, мы можем разделить счет на 5. Но если наши оценки для каждой оценки не совпадают, т.Е.: 5, 6 и так далее. каким будет ваше решение в подходе Math.ceil? @meriton
Ответ №2:
Удалите внешний []
массив Object.values
. Object.values
уже возвращает значения в array
.
От
var values = [Object.values(gradeDict)];
Для
var values = Object.values(gradeDict);
рабочий пример:
function my_index(arr, score) {
for (const [index, elem] of arr.entries()) {
if (elem.includes(score)) {
return index;
}
}
}
function getGrade(score) {
let grade;
var gradeDict = {
A: [26, 27, 28, 29, 30],
B: [21, 22, 23, 24, 25],
C: [16, 17, 18, 19, 20],
D: [11, 12, 13, 14, 15],
E: [6, 7, 8, 9, 10],
F: [0, 1, 2, 3, 4, 5],
};
var keys = Object.keys(gradeDict);
var values = Object.values(gradeDict);
grade = keys[my_index(values, score)];
return grade;
}
console.log(getGrade(5));
console.log(getGrade(25));
Альтернативное решение
function getGrade(score) {
let grade;
var gradeDict = {
A: [26, 27, 28, 29, 30],
B: [21, 22, 23, 24, 25],
C: [16, 17, 18, 19, 20],
D: [11, 12, 13, 14, 15],
E: [6, 7, 8, 9, 10],
F: [0, 1, 2, 3, 4, 5],
};
for (let key in gradeDict) {
if (gradeDict[key].includes(score)) return key;
}
return "Not found";
}
console.log(getGrade(5));
console.log(getGrade(25));
Комментарии:
1. Спасибо, чувак, как предложил @meriton. Это работает таким образом
2. @ImtiazAhmed включено альтернативное решение
3. Вы также можете искать элемент в массиве, используя
find
,filter
также.4. Спасибо, чувак! Я ценю это. Решение, исключающее метод my_index, является потрясающим.
Ответ №3:
Мне нравится ceil
решение, предложенное ранее, но вот еще одно общее решение на случай, если оно окажется полезным:
function grade(score) {
if (score < 0 || score > 30) throw RangeError(`Score ${score} out of range`);
for (let ii = 5; ii >= 0; ii--) {
if (score > 5*ii) return String.fromCharCode(70 - ii);
}
return 'F';
}
console.log(0, '=>', grade(0)) // F
console.log(4, '=>', grade(4)) // F
console.log(6, '=>', grade(6)) // E
console.log(10, '=>', grade(10)) // E
console.log(27, '=>', grade(27)) // A
console.log(30, '=>', grade(30)) // A
Комментарии:
1. При попытке другого подхода я на самом деле боролся с условием ‘0> оценка> 30’