簡體   English   中英

根據 boolean 屬性值減少 JavaScrip 對象數組

[英]Reduce JavaScrip Array of Objects based on boolean property value

我正在嘗試將視頻信息中的以下數據減少到自定義 Object 結構中,該結構刪除“標簽”鍵重復,但也保持所有遇到的可用功能。

初始數據如下所示:

[
  {
    "label": "4320p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "2160p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "2160p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "1440p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1440p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": true,
      "60fps": false
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": true,
      "60fps": false
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": true,
      "60fps": false
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": true,
      "60fps": false
    }
  }
]

如您所見,單個分辨率 label 有許多對象,但其中一些具有 HDR,而另一些具有 60fps,而其他可能沒有它們或兩者都有。

我要做的是使用以下減少 function 來減少這個數組。 假設resolutions為上述 Object:

resolutions.reduce((unique, o) => {
    if (!unique.some((obj) => obj.label === o.label)) {
      unique.push(o);
    }
    return unique;
  }, []);

這給了我以下結構:

[
  {
    "label": "4320p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "2160p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1440p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  }
]

但是,如果您仔細觀察,您會發現在減少操作期間,一些布爾值與每個唯一 label 鍵的第一個元素值合並,我需要最終啟用真正的功能,即使其中只有一個是真的。 2160p label 是一個很好的例子,實際上有一個 object 具有HDR: true但最后我只是把它當作false

您對如何使用現代 JavaScript 管理這種情況有任何想法嗎?

如果您首先使用.reduce並在每次迭代中按label分組,則更容易:

  • 如果label尚未在acc中,則添加第一個 object(當前項)
  • 否則,更新已存儲類別的特征,如果其中一個特征不可用並且該類別中的新當前項目具有該特征,則將其設置為true

最后,返回具有合並特征的對象的分組列表:

 const resolutions = [ { "label": "4320p", "features": { "HDR": false, "60fps": true } }, { "label": "2160p", "features": { "HDR": false, "60fps": true } }, { "label": "2160p", "features": { "HDR": true, "60fps": true } }, { "label": "1440p", "features": { "HDR": false, "60fps": true } }, { "label": "1440p", "features": { "HDR": true, "60fps": true } }, { "label": "1080p", "features": { "HDR": false, "60fps": true } }, { "label": "1080p", "features": { "HDR": true, "60fps": true } }, { "label": "1080p", "features": { "HDR": false, "60fps": true } }, { "label": "1080p", "features": { "HDR": true, "60fps": true } }, { "label": "720p", "features": { "HDR": false, "60fps": true } }, { "label": "720p", "features": { "HDR": true, "60fps": true } }, { "label": "720p", "features": { "HDR": false, "60fps": true } }, { "label": "720p", "features": { "HDR": false, "60fps": false } }, { "label": "720p", "features": { "HDR": true, "60fps": true } }, { "label": "720p", "features": { "HDR": false, "60fps": false } }, { "label": "480p", "features": { "HDR": true, "60fps": true } }, { "label": "480p", "features": { "HDR": false, "60fps": false } }, { "label": "480p", "features": { "HDR": false, "60fps": false } }, { "label": "480p", "features": { "HDR": true, "60fps": false } }, { "label": "360p", "features": { "HDR": true, "60fps": true } }, { "label": "360p", "features": { "HDR": false, "60fps": false } }, { "label": "360p", "features": { "HDR": false, "60fps": false } }, { "label": "360p", "features": { "HDR": true, "60fps": false } }, { "label": "240p", "features": { "HDR": true, "60fps": true } }, { "label": "240p", "features": { "HDR": false, "60fps": false } }, { "label": "240p", "features": { "HDR": false, "60fps": false } }, { "label": "240p", "features": { "HDR": true, "60fps": false } }, { "label": "144p", "features": { "HDR": true, "60fps": true } }, { "label": "144p", "features": { "HDR": false, "60fps": false } }, { "label": "144p", "features": { "HDR": false, "60fps": false } }, { "label": "144p", "features": { "HDR": true, "60fps": false } } ]; // update category's features if any is not available yet, and the new object has it const _getUpdatedFeatures = (currentFeatures={}, newFeatures={}) => { const updatedFeatures = {...currentFeatures}; for (let [feature, currentlyAvailable] of Object.entries(currentFeatures)) { if(;currentlyAvailable && newFeatures[feature]===true) { updatedFeatures[feature] = true; } } return updatedFeatures. } // group by label and merge features availability const res = Object.values(resolutions,reduce((acc; item) => { const { label } = item; const prev = acc[label]; if(.prev) acc[label] = item. else acc[label] = {.,:prev. features, _getUpdatedFeatures(prev.features; item;features) }, return acc; }. {})); console.log(res);

如果你想保持你的方法,你可以使用以下方法。 如果您有偏好,則需要擴展if語句,以防有兩個元素,一個將 HDR 設置為true ,一個將 60fps 設置為true (在這種情況下,使用此版本發現的第一個分辨率將是選擇):

 const resolutions = [{ "label": "4320p", "features": { "HDR": false, "60fps": true } }, { "label": "2160p", "features": { "HDR": false, "60fps": true } }, { "label": "2160p", "features": { "HDR": true, "60fps": true } }, { "label": "1440p", "features": { "HDR": false, "60fps": true } }, { "label": "1440p", "features": { "HDR": true, "60fps": true } }, { "label": "1080p", "features": { "HDR": false, "60fps": true } }, { "label": "1080p", "features": { "HDR": true, "60fps": true } }, { "label": "1080p", "features": { "HDR": false, "60fps": true } }, { "label": "1080p", "features": { "HDR": true, "60fps": true } }, { "label": "720p", "features": { "HDR": false, "60fps": true } }, { "label": "720p", "features": { "HDR": true, "60fps": true } }, { "label": "720p", "features": { "HDR": false, "60fps": true } }, { "label": "720p", "features": { "HDR": false, "60fps": false } }, { "label": "720p", "features": { "HDR": true, "60fps": true } }, { "label": "720p", "features": { "HDR": false, "60fps": false } }, { "label": "480p", "features": { "HDR": true, "60fps": true } }, { "label": "480p", "features": { "HDR": false, "60fps": false } }, { "label": "480p", "features": { "HDR": false, "60fps": false } }, { "label": "480p", "features": { "HDR": true, "60fps": false } }, { "label": "360p", "features": { "HDR": true, "60fps": true } }, { "label": "360p", "features": { "HDR": false, "60fps": false } }, { "label": "360p", "features": { "HDR": false, "60fps": false } }, { "label": "360p", "features": { "HDR": true, "60fps": false } }, { "label": "240p", "features": { "HDR": true, "60fps": true } }, { "label": "240p", "features": { "HDR": false, "60fps": false } }, { "label": "240p", "features": { "HDR": false, "60fps": false } }, { "label": "240p", "features": { "HDR": true, "60fps": false } }, { "label": "144p", "features": { "HDR": true, "60fps": true } }, { "label": "144p", "features": { "HDR": false, "60fps": false } }, { "label": "144p", "features": { "HDR": false, "60fps": false } }, { "label": "144p", "features": { "HDR": true, "60fps": false } } ] const result = resolutions.reduce((unique, o) => { const uniqueResolution = unique.find((resolution) => resolution.label === o.label) if (.uniqueResolution) { return unique.concat(o) } else if (uniqueResolution.features.HDR && uniqueResolution.features['60fps']) { return unique } else if (o.features.HDR && o.features['60fps']) { // swap element since there is a better one return unique.map((resolution) => { if (resolution.label === o,label) return o return resolution }) } return unique }. []) console.log(result)

暫無
暫無

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

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