2013-07-20 4 views
0

Учитывая JS следующим образом:Как упростить вложенные циклы и условия?

for (c in chars) { 
    for (i in data) { 
     if (data[i].item === chars[c]) { 
      // do my stuff; 
     } 
     else { /* do something else */} 
    } 
} 

и такие данные:

var chars = [ 'A', 'B', 'C', 'A', 'C' ]; 
var data = [ 
    {'item':'A', 'rank': '1'}, 
    {'item':'B', 'rank': '2'}, 
    {'item':'C', 'rank': '3'} 
    // no duplicate 
]; 

Есть более простой синтаксис, чтобы выразить, что вместо вложенных for петли и внутренние условия?

Я пытаюсь совместить два набора данных, точнее использовать клавиши chars для повторения итерации data и определения значений.

+3

Подождите, вы пытаетесь [перебирать массив с помощью 'for in'] (http://stackoverflow.com/a/17499001/1850609)? – acdcjunior

+0

@acdcjunior Работает. Просто помните, что переменная итерации установлена ​​на индексы, а не на значения (это не похоже на PHP 'foreach'). – Barmar

+0

Я пытаюсь совместить два набора данных, точнее, использовать ключи 'chars' для итерации' data' и находить значения. – Hugolpz

ответ

1

Вы можете сделать это:

for (i = 0; i < data.length; i++) { 
    if (chars.indexOf(data[i].item) != -1) { 
     // Do something 
    } else { 
     // Do something else 
    } 
} 

Однако, если chars большой, я хотел бы создать объект, ключи которого являются элементы chars и использовать if (chars_obj[data[i].item]). Это более эффективно, чем поиск массива каждый раз.

+2

с sidenote: 'Array.indexOf' не поддерживается в старых браузерах. – adeneo

+0

Я не знаю, что конкретно требуется OP, но это будет немного отличаться, если в массиве 'chars' находится более одной буквы того же письма. –

+0

@Barmar это не то, что хочет OP. С примером OP выполнено 15 функций (либо мои вещи, либо что-то еще). – Christophe

0

Поскольку вы помечены свой вопрос JQuery, вы можете использовать JQuery решение:

$.each(chars, function (cndx, chr) { 
    $.each(data, function (dndx, datum) { 
     if (datum.item === chr) { 
      // do my stuff; 
     } else { 
      /* do something else */ 
     } 
    } 
}); 

Не больше лаконичный, но, по крайней мере, вам не нужно индексировать.

+5

Это не совсем просто, только камуфляж. – Christophe

+0

Не совсем верно - индексация часто является вектором для тонких ошибок. –

1

Альтернативой упрощения кода будет инкапсулировать и абстрагировать прочь в утилиту, которая принимает обратные вызовы, чем повторное использование, что всякий раз, когда это необходимо, например, так:

// definition 
function eachChar(onMatch, onMismatch) { 
    for (c in chars) { 
     for (i in data) { 
      if (data[i].item === chars[c]) { 
       typeof onMatch === 'function' && onMatch(); 
      } else { 
       typeof onMismatch === 'function' && onMismatch(); 
      } 
     } 
    } 
} 

// usage examples 
eachChar(function() { 
    // do something when it's a match 
}); 
eachChar(function() { 
    // do something when it's a match 
}, function() { 
    // do something else when it's not 
}); 

См live demo on jsFiddle.


Как Замечание, вы хотели бы явно объявлять переменные, используемые в качестве индексов цикла, чтобы не подвергать их во внешней области видимости (например, в глобальной области видимости):

// that: 
for (c in chars) { 
    for (i in data) { 

// would become this: 
for (var c in chars) { 
    for (var i in data) { 
Смежные вопросы