2016-12-07 3 views
2

Я работаю с ES6 и React. Я просматриваю объект ответа из службы Java Rest, и мне стало ясно, что, возможно, существует более чистый способ разбора объекта на два объекта. Этот wokrs, он просто выглядит неуклюжим.Есть ли более чистый способ сортировки списка?

  let draftList = []; 
      let readyForApprovalList = []; 
      for (let i = 0; i < action.allStatusesSurveysList.length; i++){ 
       if (action.allStatusesSurveysList[i].status === statusTypes.DRAFT){ 
        draftList.push(action.allStatusesSurveysList[i]); 
       } else if (action.allStatusesSurveysList[i].status === statusTypes.READY_FOR_APPROVAL){ 
        readyForApprovalList.push(action.allStatusesSurveysList[i]); 
       } 
      } 
+0

'map()' и/или 'filter()'. –

ответ

2

Сочетание Array.prototype.filter() и arrow filter functions будет довольно чистое решение.

Обратите внимание, что хотя это решение является приятным и читаемым, оно не является наиболее эффективным, так как требуется как минимум две итерации массива. Тем не менее, он вполне может быть достаточно эффективным для подавляющего большинства случаев использования и по этой причине является хорошим компромиссом.

const draftList = action.allStatusesSurveysList 
    .filter(i => i.status === statusTypes.DRAFT) 
const readyForApprovalList = action.allStatusesSurveysList 
    .filter(i => i.status === statusTypes.READY_FOR_APPROVAL) 

Можно даже извлечь функцию состояния фильтра дополнительно:

const byStatus = status => item => item.status === status 

const draftList = action.allStatusesSurveysList 
    .filter(byStatus(statusTypes.DRAFT)) 
const readyForApprovalList = action.allStatusesSurveysList 
    .filter(byStatus(statusTypes.READY_FOR_APPROVAL)) 
1

forEach вероятно, будет работать лучше здесь - в то время как вы можете использовать filter, потребуется один проход для каждого типа категории.

action.allStatusesSurveysList.forEach(function(item) { 
    switch(item.status) { 
     case statusTypes.DRAFT: 
      draftList.push(item); 
      break; 
     case statusTypes.READY_FOR_APPROVAL: 
      readyForApprovalList.push(item); 
      break; 
     default: 
      // "unknown status" list?? 
    } 
}); 

Это перебрать массив и имеет аккуратный EXTRA использования item вместо многократного ввода action.allStatusesSurveysList[i]. Кроме того, использование оператора switch лучше, чем if..else if..

+0

Я думаю, что разделение цикла и запуск двух 'filter' - это более оптимизированный подход, чем 'forEach' и' switch-case', так как есть только два случая. Этот 'switch-case' будет внутренне конвертировать в' if-else' в любом случае. – Quirk

+0

@Quirk Возможно, но метод 'filter' повторяется по одному и тому же массиву несколько раз, и это кажется неуклюжим для меня, когда требуется только одна итерация. Я также чувствую, что мой метод 'switch' более расширяем, если нужны будущие статусы. –

+0

Я согласен, когда задействовано более двух случаев, оно имеет смысл и более читаемо. В противном случае, я почти всегда думаю об этом: http://stackoverflow.com/a/11227902/2844164 – Quirk

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