JavaScript: оператор else внутри цикла for..in нарушает мой оператор if

У меня есть оператор if внутри цикла for in, который работает нормально, но когда я добавляю оператор else в конце, код ломается, так как переменная (в данном случае ключ) из цикла for..in не передается в цикл else. утверждение. Вот код:

config = {'test1':2, 'test2':2, 'test3':5, 'test4':8}

  for (key in config) {
    if (isNaN(item)) {
      return item;
    }
    if (key.indexOf(baseCcy) !== -1) {
      console.log("match config");
      item = parseFloat(item).toFixed(config[key]);
      return item;
    } else {
      item = parseFloat(item).toFixed(10);
      return item;
    }
  }

baseCcy и item являются входными данными из angular из следующего кода: | {{fill.price | decimalFilter:baseCcy}} Целью этого является создание пользовательского фильтра, и я делаю цикл for..in внутри фильтра для его достижения. До сих пор это работало хорошо, но оператор else просто ломал его. Суть оператора else в том, что если ни один из входных данных из item не соответствует массиву конфигурации, вернуть элемент с 10 десятичными знаками.

Следует отметить, что когда я запускаю console.log key после цикла for..in, он показывает мне только «test1», но когда я удаляю оператор else (только с двумя if), ключ console.log показывает мне «test1», « тест2", "тест3", "тест4". '


person Mjaaay    schedule 23.02.2016    source источник
comment
И if, и else имеют оператор return, поэтому ваш цикл for всегда будет останавливаться после первого элемента. Я думаю, что вы хотите, так это переместить тело else после цикла, чтобы это происходило только в том случае, если ни один из элементов не соответствует условию if к концу цикла.   -  person nnnnnn    schedule 23.02.2016
comment
Как вы предлагаете использовать цикл for? Вы хотите, наконец, вернуть все элементы или вернуть элемент для самого первого цикла ??   -  person Rajshekar Reddy    schedule 23.02.2016
comment
@Reddy Цель цикла for — получить все имена свойств конфигурации массива («test1», «test2»). Затем запустите оператор if, чтобы сопоставить ввод (элемент) с переменной из for..in (ключ). Во-первых, if вернет мне элемент в состоянии по умолчанию, если это NaN, второй оператор if, если основная часть, а затем оператор else, если ввод ничего не соответствует, вернет значение по умолчанию + 10 знаков после запятой.   -  person Mjaaay    schedule 23.02.2016
comment
@Mjaaay проверьте мой ответ и дайте мне знать, если это поможет.   -  person Rajshekar Reddy    schedule 23.02.2016


Ответы (2)


Просто внесите некоторые изменения в вашу текущую логику, это должно сработать для вас.

config = {'test1':2, 'test2':2, 'test3':5, 'test4':8}
var newItemValue; // a new varialble
  for (key in config) {    
    if (isNaN(item)) {
      newItemValue = item
      break;  //break once you find the match
     //return item;      
    }
    else if (key.indexOf(baseCcy) !== -1) {
      console.log("match config");
      item = parseFloat(item).toFixed(config[key]);
      newItemValue = item
      break;//break once you find the match
      //return item;       
    } 
  }
  //if the loop was a failure, then do this by default.
  if(typeof newItemValue === 'undefined'){  // check if there is no value assigned to the new variable, if its not then the loop was a failure
      item = parseFloat(item).toFixed(10);
      newItemValue = item     
  }

Вот ссылка на Рабочий JsFiddle

Выход вышеуказанной логики (когда item = 12.12345678 и baseCcy ='test3')

12.12346

EDIT: После прочтения вашего последнего комментария я думаю, что это то, что вы хотите.

  config = {'test1':2, 'test2':2, 'test3':5, 'test4':8}

  for (key in config) {
    if (isNaN(item)) {
      return item;
    }
    if (key.indexOf(baseCcy) !== -1) {
      console.log("match config");
      item = parseFloat(item).toFixed(config[key]);
      return item;
    } 
  }
  //if the program has reached this line then the loop was a failure
  item = parseFloat(item).toFixed(10);
  return item;

Здесь не нужны новые переменные, еще что-то и прочее.

person Rajshekar Reddy    schedule 23.02.2016
comment
Я создаю новый объект, который представляет собой модифицированную версию вашей конфигурации. - person Rajshekar Reddy; 23.02.2016
comment
хорошо, позвольте мне изменить логику, я думал, что item был вашим текущим циклом значения свойства объекта - person Rajshekar Reddy; 23.02.2016
comment
Виноват! Я не предоставил всех подробностей, потому что это беспорядочная кодовая база + я предположил, что в ней была очевидная ошибка новичка. В будущем я постараюсь изолировать код и предоставить jsfiddle, позвольте мне взглянуть на вашу помощь, и я скоро вернусь. - person Mjaaay; 23.02.2016
comment
@Mjaaay Также обновил скрипку, используйте новую ссылку в ответе. - person Rajshekar Reddy; 23.02.2016
comment
Это сработало! Замена else statement на новый if typeof была ключом к ее исправлению. Я не уверен на 100%, почему, но я собираюсь прочитать об этом. Кроме того, поскольку это настраиваемый фильтр в angular, мне нужно было добавить return newItemValue в конец каждого оператора if и удалить разрыв, я думаю, именно так работает angular! Спасибо Редди! редактировать: я удалил некоторые из своих предыдущих комментариев, чтобы люди могли видеть этот комментарий, не нажимая кнопку «Показать больше комментариев». - person Mjaaay; 23.02.2016
comment
@Mjaaay рад узнать, что это помогает. Также я обновил свой ответ новым кодом. Я думаю, это то, что вы хотите. До сих пор мы боролись с минимальными данными, которые вы предоставили :), поэтому сначала не могли дать вам этот код - person Rajshekar Reddy; 23.02.2016
comment
Ага! Я реорганизовал его следующим образом, и он тоже работает. for (key in config) { if (isNaN(item)) { return item; } else if (key.indexOf(baseCcy) !== -1) { item = parseFloat(item).toFixed(config[key]); return item; } } if (typeof item === 'string') { item = parseFloat(item).toFixed(2); return item; } Я думаю, что это позволило сократить код примерно на 40%. - person Mjaaay; 23.02.2016

Вы можете вернуться только из функции!

Если вы хотите выйти из структуры цикла, используйте break.

Ссылка на соответствующий документ.

Пример:

var conf;

for (key in config) {

    var item = config[key];

    if (isNaN(item)) {
        conf = item;
        break;
    }
    if (key.indexOf(baseCcy) !== -1) {
        console.log("match config");
        item = parseFloat(item).toFixed(config[key]);
        conf = item;
        break;
    } else {
        item = parseFloat(item).toFixed(10);
        conf = item;
        break;
    }
}
person Damien Fayol    schedule 23.02.2016
comment
Эй, это если на самом деле функция внутри моего контроллера. Я не думал, что мне нужно включать весь код, мой плохой. Он выглядит примерно так: app.filter('decimalFilter', function() { return function(item) { var baseCcy, config, key; и т. д. Я заявил, что код работает, но не с оператором else, и я предположил, что этого достаточно, чтобы подразумевать, что это уже была функция - person Mjaaay; 23.02.2016
comment
Пожалуйста, опубликуйте Jsfiddle, чтобы мы могли исследовать - person Damien Fayol; 23.02.2016
comment
извините, что не придумал скрипку, я предположил, что в моем выражении if была очевидная ошибка новичка, но теперь я вижу, что мне нужно предоставить больше деталей. Позвольте мне немного просмотреть и посмотреть, смогу ли я создать скрипку - person Mjaaay; 23.02.2016