【问题标题】:Find object in array with fallback condition在具有回退条件的数组中查找对象
【发布时间】:2023-03-31 17:06:01
【问题描述】:

我需要通过以下方式在数组中找到一个对象:

  • 获取第一个有效对象
  • 如果没有有效对象,返回最大版本的对象

对象的接口:

interface Data {
    version: number;
    valid: boolean;
}

样本数据:

const data = [{version: 1, valid: false}, {version: 2, valid: false}, {version: 3, valid: false}];
// return {version: 3, valid: false} because there is no valid object and the greatest version is 3


const data2 = [{version: 1, valid: false}, {version: 2, valid: true}, {version: 3, valid: true}];
// return {version: 2, valid: true} because this is the first valid object

如果我过滤数组,它仅适用于第二个样本,因为我无法再次循环数组以获得最大版本:

data.find(d => d.valid); // undefined
data2.find(d => d.valid); // {version: 2, valid: true}

游乐场:

const data = [{version: 1, valid: false}, {version: 2, valid: false}, {version: 3, valid: false}];
const data2 = [{version: 1, valid: false}, {version: 2, valid: true}, {version: 3, valid: true}];


console.log(data.find(d => d.valid));
console.log(data2.find(d => d.valid));

【问题讨论】:

    标签: javascript arrays algorithm


    【解决方案1】:

    您可以按您的标准排序并返回第一个对象:

    result = [...data].sort((a, b) => a.valid - b.valid || a.version - b.version).pop()
    

    如果你害怕这样“效率低下”,你也可以使用这样的简单循环

    function find(data) {
        let maxVer = data[0]
        
        for (let d of data) {
            if (d.valid)
                return d
            if (d.version > maxVer.version)
                maxVer = d
        }
        
        return maxVer
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用Array.prototype.find() 检查是否存在有效对象,使用Array.prototype.reduce() 检查是否存在最大版本,如下所示:

      const data = [{version: 1, valid: false}, {version: 2, valid: false}, {version: 3, valid: false}];
      // return {version: 3, valid: false} because there is no valid object and the greatest version is 3
      
      
      const data2 = [{version: 1, valid: false}, {version: 2, valid: true}, {version: 3, valid: true}];
      // return {version: 2, valid: true} because this is the first valid object
      
      function findFirstValidOrGreatestVersion(data) {
        return data.find(({ valid }) => valid) || data.reduce((acc, cur) => acc.version < cur.version ? cur : acc);
      }
      
      console.log(findFirstValidOrGreatestVersion(data));
      console.log(findFirstValidOrGreatestVersion(data2));

      【讨论】:

        【解决方案3】:

        如果您关闭了一个变量,例如跟踪您的最大对象的 maxObject,您可以运行.find(),同时在您的数组的一次遍历中找到最大对象:

        const data = [{version: 1, valid: false}, {version: 2, valid: false}, {version: 3, valid: false}];
        const data2 = [{version: 1, valid: false}, {version: 2, valid: true}, {version: 3, valid: true}];
        
        const getObj = data => {
          let maxObj = {version: -Infinity};
          const res = data.find((data) => {
            maxObj = data.version > maxObj.version ? data : maxObj; 
            return data.valid;
          });
          return res || maxObj;
        }; 
        
        console.log(getObj(data));
        console.log(getObj(data2));

        【讨论】:

          【解决方案4】:

          如果需要找到O(n)的对象,则尝试使用reduce方法遍历数组并检查条件:

          const data = [{version: 1, valid: false}, {version: 2, valid: false}, {version: 3, valid: false}];
          
          const anObject = data.reduce((a, {version, valid})=> {
            if (Object.keys(a).length == 0) {
              a[version] = {version, valid};
              return a;
            }
            let acc_key = Object.keys(a)[0] ;
          
            if (a[acc_key].valid) return a;
          
            if (version > acc_key) {
              delete a[acc_key];
              a[version] = {version, valid};
            }
            return a;
          },{});
          
          console.log(Object.values(anObject));

          还有一个案例:

          const data2 = [{version: 1, valid: false}, {version: 2, valid: true}, {version: 3, valid: true}];
          
          const anObject = data2.reduce((a, {version, valid})=> {
            if (Object.keys(a).length == 0) {
              a[version] = {version, valid};
              return a;
            }
            let acc_key = Object.keys(a)[0] ;
          
            if (a[acc_key].valid) return a;
          
            if (version > acc_key) {
              delete a[acc_key];
              a[version] = {version, valid};
            }
            return a;
          },{});
          
          console.log(Object.values(anObject));

          【讨论】:

            猜你喜欢
            • 2021-12-10
            • 2014-11-22
            • 1970-01-01
            • 2017-07-22
            • 1970-01-01
            • 2021-12-06
            • 2019-12-16
            • 2019-12-03
            • 2014-05-07
            相关资源
            最近更新 更多