簡體   English   中英

有沒有辦法重構這個 AND 和 XOR 邏輯分支?

[英]Is there a way to refactor this AND and XOR logical branch?

我有 2 個用戶 ID,如果我只有一個或兩個,我想做不同但非常相似的邏輯。 有沒有辦法整合這段代碼,因為現在它看起來很丑。


function getUserPermission(primaryId, secondaryId, role) {
  let permission = userInfo.permissionList.filter( permission => {

    //logical AND
    if(primaryId && secondaryId){
      // have both IDs, use both IDs
      (permission.primaryId === primaryId && permission.secondaryId === secondaryId) && permission.role === role
    } 

    //logical XOR
    else if((primaryId && !secondaryId) || (!primaryId && secondaryId)) {
      // have only 1 ID, use 1 ID 
      (permission.primaryId === primaryId || permission.secondaryId === secondaryId) && permission.role === role
    }

  })[0]

  return permission
}

像這樣的事情呢?

if(!primaryId && !secondaryId) {
  throw Error("No ID was provided");
}
let permission = userInfo.permissionList.filter(p => p.role === role);
if(primaryId) {
  permission = permission.filter(p => p.primaryId === primaryId);
}
if(secondaryId) {
  permission = permission.filter(p => p.secondaryId === secondaryId);
}
return permission[0];

首先,當兩個 id 都無效時,這個邏輯似乎無法處理。 您將希望以某種方式處理該問題(到目前為止,其他答案似乎都包括這些方面的內容)。

接下來,由於您只返回第一個匹配權限,我建議使用一旦找到第一個匹配項就不會繼續循環的解決方案。 在這方面,對於這個用例, Array.find()Array.filter()好得多。

如果我將其他答案放在一起,那將是這樣的:

function getUserPermission(primaryId, secondaryId, role) {
  if (!primaryId && !secondaryId) return null // at least one must be populated, why loop at all?
  return userInfo.permissionList.find(permission => 
    permission.role === role
      && (!primaryId || primaryId === permission.primaryId) // if primary is populated, it needs to match
      && (!secondaryId || secondaryId === permission.secondaryId) // if secondary is populated, it needs to match
  );
}

...但這並不能處理完全有效的 ID 恰好為 0 的情況。不過,這可能取決於您的數據。 例如,也許您總是使用基於字符串的 ID。 它還會檢查每個循環上的有效 ID(您可能會或可能不會完全滿意)

考慮到這些潛在問題,我對您的數據/類型做了一些假設,並提出了一種更非正統的方法來解決它們:

const getUserPermission = (primaryId = -1, secondaryId = -1, role = '') => {
  if (primaryId < 0 && secondaryId < 0) return null

  const conditions = [ p => p.role === role ]
    .concat(primaryId >= 0 ? [ p => p.primaryId === primaryId ] : [])
    .concat(secondaryId >= 0 ? [ p => p.secondaryId === secondaryId ] : [])

  return userInfo.permissionList.find(p => conditions.every(fn => fn(p)))
}

...最后一個創建了一組函數, conditions ,以檢查每個權限。 應該返回匹配每個條件的第一個(理論上,至少 - 我沒有測試它)

function getUserPermission(primaryId, secondaryId, role) {
  return userInfo.permissionList.find(permission => 
    permission.role === role
      && (!!primaryId || !!secondaryId)// at least one is populated
      && (!primaryId || primaryId === permission.primaryId)// if primary is populated, it needs to match
      && (!secondaryId || secondaryId === permission.secondaryId)// if secondary is populated, it needs to match
    );
}

這與您的代碼略有不同,因為如果沒有匹配,它將返回 null,而您的則拋出異常。 如果你想扔,你總是可以把結果放在一個變量中並檢查 null。

這個重構怎么樣:

function getUserPermission(primaryId = undefined,secondaryId = undefined,role) {

  primaryId === undefined && secondaryId === undefined && throw new Error("Ids are required");

  const userPermission = userInfo.permissionList
    .filter((permission) => role && permission.role === role)
    .filter((permission) => primaryId && permission.primaryId === primaryId)
    .filter(
      (permission) => secondaryId && permission.secondaryId === secondaryId
    );

  return userPermission[0];
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM