#javascript #arrays #jslint
#javascript #массивы #jslint
Вопрос:
У меня ситуация, когда мне нужно получить доступ к массиву нокаута multidimension с координатами, неизвестными до времени выполнения.
Возможные нокаутирующие массивы (это может быть любой из тех, которые не известны до времени выполнения)
self.customers[0]
self.customers[0][0]
self.customers[0][0][0]
self.customers[0][0][0][0]
self.customers[0][0][0][0][0]
У меня есть код, который дает мне комбинацию массивов в строковом литерале, как показано ниже
level = "[0]"
level = "[0][0]"
level = "[0][0][0]"
level = "[0][0][0][0]"
level = "[0][0][0][0][0]"
вычисление значения в массиве следующим образом
arr = arr.concat(eval('self.customers()' level));
Я знаю, что это работает, и это плохой способ. JSLint говорит, что «eval — это зло»
> Есть ли лучший способ получить доступ к массиву self.customers()[i][j[k]… где i, j, k … могут быть созданы во время выполнения
Ответ №1:
На самом деле это не вопрос, связанный с нокаутом. В любом случае, есть несколько способов решить эту проблему без использования eval
, некоторые из которых более умны, чем другие. Вот простой (хотя и не обязательно самый элегантный) способ сделать это.
Предположим:
var self = {
customers: [[[1],[[2,3,4],5]],[6],[7,[8,9]]]
};
var level = "[0][1][0][2]";
Ожидаемый результат будет «4». Теперь сначала найдите уровни, например, используя регулярное выражение:
var myLevels = level.match(/d /g);
И используйте рекурсивную функцию для перехода в многомерный массив:
function multiDimensionFind(data, levels) {
var result = data[levels[0]];
if (result instanceof Array) {
levels.splice(0, 1);
return multiDimensionFind(result, levels);
}
return resu<
}
var x = multiDimensionFind(self.customers, myLevels);
Посмотрите на эту скрипку, чтобы увидеть ее в действии.
PS. Я бы переосмыслил ваш дизайн;-)
Комментарии:
1. это отлично работает. единственное, чего мне не хватает, как получить значение как наблюдаемое, предполагая, что self.customers является нокаутом, наблюдаемым
2. Вероятно, вы получите лучший ответ, если опубликуете следующий вопрос (возможно, ссылку на этот) с кодом / проблемой, относящимся к нокауту. Попробуйте включить в вопрос минимальный код для воспроизведения и, если это вообще возможно, добавьте скрипку (возможно, мой fork), чтобы продемонстрировать проблему. Удачи!
Ответ №2:
Вы могли бы создать вспомогательную функцию, которая возвращает правильный уровень на основе входных данных. Что-то вроде этого
var getLevel = function (arr, levels) {
var retArr = arr();
while(levels) {
try {
var currLvl = parseInt(levels.substring(1,2)); //get first level
if (retArr) {
retArr = retArr[currLvl]; //navigate to given level
} else {
//what happens if the array doesn't have enough levels?
}
levels = levels.substring(3); // go to next level
} catch (ex) {
console.log(ex);
//what should happen if the levels string has a wrong format?
}
}
return retArr;
}
Конечно, вы также должны определить, что должно произойти, когда входные данные недопустимы или они не определены.
Затем вы бы вызвали этот метод как таковой : getLevel(self.customers, level);
, таким образом избегая eval 🙂