2013-08-23 2 views
0

Кто-нибудь знает, как я могу уменьшить дублирование в утверждении соответствия шаблонов в следующей функции? в частности, я хочу обобщить оператор if. Я думаю, если бы я мог каким-то образом передать свойства объекта в функцию, тогда я мог бы это сделать, но я понятия не имею, как это сделать. Буду признателен за любую оказанную помощь. БЛАГОДАРЯ!!Как реорганизовать следующую функцию для уменьшения дублирования? Slick, Pattern Matching, Play Framework

Ex: if (ASC) _.uid.asc else _.uid.desc 

Ниже функция

/** 
    * Finds all the users and sorts by column ascending or descending. Ascending or Descending is determined by 
    * if the orderBy value is positive or negative. These values are held in constants in @package models.AdminPage 
    * @param orderBy The column to be sorted. 
    * @return a list of sorted users. 
    */ 
    def findAll(orderBy: Int = DefaultSortByUid) = DB.withSession { 
    implicit s: Session => 
     val q = for(u <- User) yield u 

     // Get the absolute value to determine the column to be sorted. A valid value will be an Int that corresponds 
     // to one of the constants defined in @package models.AdminPage. 
     val sortByColumn = orderBy.abs 
     val ASC = orderBy > 0 

     val users = q.sortBy(sortByColumn match { 
     case `SortByUid` => if (ASC) _.uid.asc else _.uid.desc 
     case `SortByUserName` => if(ASC) _.userId.asc else _.userId.desc 
     case `SortByAuthMethod` => if(ASC) _.authMethod.asc else _.authMethod.desc 
     case `SortByRole` => if(ASC) _.role.asc else _.role.desc 
     case `SortByEmail` => if(ASC) _.email.asc else _.email.desc 
     case `SortByFirstName` => if(ASC) _.firstName.asc else _.firstName.desc 
     case `SortByLastName` => if(ASC) _.lastName.asc else _.lastName.desc 
     //An invalid value just goes to table main page and to default sort of ascending by uid 
     case _ => _.uid.asc 
     }).list 

     users 
    } 

ответ

1

ли объекты колонки имеют общий родительский, на котором .desc и .asc доступны Если это так, вы делаете вспомогательную функцию:

def orderBy(direction, column) { 
    if (direction) column.asc else column.desc 
} 

и вызывать его так, как это делается в каждом из случаев:

case ... => orderBy(ASC, _.uid) 

Или даже лучше отмените его и сделайте совпадение с возвратом _.uid и используйте его как вход для orderBy

+0

Да, это то, что я пытался сделать, но я понятия не имею, какой тип _.uid есть и как передать его в функцию. Вот где я застрял. – danielbh

+0

@ danielh Похоже, вы уже поняли, что тип будет столбцом [T] – leipie

1

Это лучшее, что я могу сделать. Может ли кто-нибудь лучше?

/** 
    * Find all users and sort by column, ascending or descending. 
    * 
    * @param orderBy Column to be sorted. 
    * @return Sorted list of users. 
    */ 
    def findAll(orderBy: Int = DefaultSortByUid) = DB.withSession { 
    implicit s: Session => 
    val q = for(u <- User) yield u 

    // Ascending or Descending is determined by the sign of orderBy. 
    def sort[T] (column: Column[T]) = if (orderBy > 0) column.asc else column.desc 

    // Case values are defined as constants in @class models.AdminPage 
    q.sortBy(c => sort(orderBy.abs match { 
    case `SortByUserName` => c.userId 
    case `SortByAuthMethod` => c.authMethod 
    case `SortByRole` => c.role 
    case `SortByEmail` => c.email 
    case `SortByFirstName` => c.firstName 
    case `SortByLastName` => c.lastName 
    case _ => c.uid 
    })).list 
    } 
1

Я думаю, что это может быть то, что вы ищете:

/** Find all users and sort by column, ascending or descending. 
    * 
    * @param column Column to be sorted. 
    * @param asc  Sort ascending. 
    * @return  Sorted list of users. 
    */ 
def findAll[T <% Ordered](column: User => T = _.uid, asc: Boolean = true) = DB withSession { 
    def sort(r: Records) = if (asc) column(r).asc else column(r).desc 
    val q = for(u <- User) yield u 
    q.sortBy(sort).list 
} 

Вы бы использовать его как это:

val usersByEmailDesc = findAll(_.email, asc = false) 

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

+0

@ ms-ati Не просите «принять» в ответе. Не говоря уже о том, чтобы попросить принять у кого-то свой ответ. – Sumurai8

+0

@ Sumurai8 Я нахожу ваш официозный тон бесполезным. Пожалуйста, восстановите то, что вы считаете приемлемыми частями моего редактирования, и мы можем обсудить. В противном случае, пожалуйста, удаляйте полезную информацию. –