2013-08-30 4 views
1

Я работаю с API, и он возвращает данные мне в нечетном формате. Или это по крайней мере для меня. Данные - часы работы магазина, я хочу их сопоставить с тем, как они мне нужны в интерфейсе (приложение написано в Angular, использует два API, поэтому мне нужно заставить API работать с моей логикой Я не хочу, чтобы приспособиться к их формату)JavaScript: оптимизация цикла внутри цикла внутри цикла

Это формат данных, поступающие из API:

var operatingHoursArray = [ 
    {Weds: true, End: "17:00", Start: "09:00"}, 
    {Tue: true, End: "17:00", Start: "09:00"}, 
    {Thur: true, End: "17:00", Start: "09:00"}, 
    {Sun: false, End: "", Start: ""}, 
    {Sat: true, End: "17:00", Start: "09:00"}, 
    {Mon: true, End: "17:00", Start: "09:00"}, 
    {Fri: true, End: "17:00", Start: "09:00"} 
] 

Странная структура ИМО, я предпочел бы в дни недели быть объектами, затем открытые и закрытые часы, заключенные в них. Мое приложение (AngularJS) требует данных, чтобы быть в следующем формате:

var formattedHours = { 
    Sunday: 'Closed', 
    Monday: 'Closed', 
    Tuesday: 'Closed', 
    Wednesday: 'Closed', 
    Thursday: 'Closed', 
    Friday: 'Closed', 
    Saturday: 'Closed' 
}; 

времена значение по умолчанию «Закрыто», это код, я использую, чтобы соответствовать день недели с форматом я требую его в:

var daysOfWeek = [ 
    { sform: 'Mon', lform: 'Monday' }, 
    { sform: 'Tue', lform: 'Tuesday' }, 
    { sform: 'Weds', lform: 'Wednesday' }, 
    { sform: 'Thur', lform: 'Thursday' }, 
    { sform: 'Fri', lform: 'Friday' }, 
    { sform: 'Sat', lform: 'Saturday' }, 
    { sform: 'Sun', lform: 'Sunday' } 
]; 

// Loop through the operating hours for the dealer 
for (var i = operatingHoursArray.length - 1; i >= 0; i--) { 
    // Loop through the property names for each day, getting the first property name (the day of week) 
    for (property in operatingHoursArray[i]) { 
     // Loop through the days of the week 
     for (var v = daysOfWeek.length - 1; v >= 0; v--) { 
      // If the day of the week (array) matches the property name, get the details 
      if(daysOfWeek[v].sform == property && operatingHoursArray[i][property] === true) { 
       formattedHours[daysOfWeek[v].lform] = operatingHoursArray[i].Start + ' - ' + operatingHoursArray[i].End; 
      } 
     }; 
     break; // Forces loop to stop after first property 
    } 
}; 

Это становится очень неприятным очень быстро, но с моим знанием (уровень нуба), я не уверен, как сделать это любым более эффективным. Он работает для того, что мне нужно, но есть ли лучший способ кодировать это? В настоящее время он должен работать 49 раз, чтобы проверять каждый день недели. Кроме того, некоторые магазины не предоставляют 7 дней в часах, вместо этого предоставляют только часы, в которые они открыты. Я не могу изменить структуру formattedHours, потому что другой API зависит от той же структуры.

+0

Если вы открыты для конечного объекта с короткими именами вместо длинного, это может быть намного быстрее. – Markasoftware

+0

'// Заставляет цикл останавливаться после первого свойства. Нет« первого свойства ». Вы не должны полагаться на порядок итераций при использовании 'for-in'. –

+0

Ооо, я не знал этого, спасибо за головы. Это действительно повредит, если они не придут в порядок: S. – Neil

ответ

4

Изменение daysOfWeek к объекту:

var daysOfWeek = { 
    Mon: "Monday", 
    Tue: "Tuesday", 
    ... 
}; 

Тогда вы можете просто получить доступ к daysOfWeek[property] вместо поиска daysOfWeek с петлей.

2

Начните с символа коротких длинномерных имен.

var daysOfWeek = { 
    'Mon': 'Monday', 
    'Tue': 'Tuesday', 
    'Weds': 'Wednesday', 
    'Thur': 'Thursday', 
    'Fri': 'Friday', 
    'Sat': 'Saturday', 
    'Sun': 'Sunday' 
]; 

for (var i = operatingHoursArray.length - 1; i >= 0; i--) { 
    // Loop through the property names for each day, getting the first property name (the day of week) 
    for (property in operatingHoursArray[i]) { 
     var dow = daysOfWeek[property]; 
     if(dow && operatingHoursArray[i][property]) { 
      formattedHours[dow] = operatingHoursArray[i].Start + ' - ' + operatingHoursArray[i].End; 
      break; 
     } 
    } 
} 
0

Я бы взял вашу заказанную коллекцию и повторил ее. Для каждого элемента я бы зациклил operatingHoursArray до тех пор, пока не найдется для текущего daysOfWeek, а затем создайте строку.

Использование .forEach() и .every() немного очищает его. .every() используется для внутреннего цикла, так что мы можем остановить итерацию после того, как совпадение найдено.

var daysOfWeek = [ 
    { sform: 'Mon', lform: 'Monday' }, 
    { sform: 'Tue', lform: 'Tuesday' }, 
    { sform: 'Weds', lform: 'Wednesday' }, 
    { sform: 'Thur', lform: 'Thursday' }, 
    { sform: 'Fri', lform: 'Friday' }, 
    { sform: 'Sat', lform: 'Saturday' }, 
    { sform: 'Sun', lform: 'Sunday' } 
]; 

daysOfWeek.forEach(function(day) { 
    operatingHoursArray.every(function(item) { 
     if (item.hasOwnProperty(day.sform)) { 
      day.formatted = item.Start + ' - ' + item.End; 
      day.start = item.Start; 
      day.end = item.End; 
      day.open = item[day.sform] 
      return false; 
     } 
    }); 
}); 

Обратите внимание, что я добавляю отформатированную строку, а также исходные данные для ваших daysOfWeek объектов.

Это то, что вы можете сохранить заказ, который вы определили. Итак, теперь вы можете искать по индексу, а также итератировать в надежном порядке, что невозможно при использовании for-in.

Смежные вопросы