Javascript Object.keys(arr).reduce() return 最低调

Javascript Object.keys(arr).reduce() return lowest key

我有 3 个不同的测试用例,每个都传递给下面的函数 getEarliest

{}

{ '2022-04-29': 1 }

{ '2022-04-29': 3, '2022-04-30': 2, '2022-04-28': 3, '2022-05-02': 2 }

从每个测试用例中,我想 return 具有最小日期和最大值的 key:value。我的问题是在第三个测试用例中,我得到的是 '2022-04-29': 3 而不是 '2022-04-28': 3

getEarliest = dates => {

    return Object.keys(dates).reduce((prev, curr) => {

        if (dates[curr] > prev.date) {
        
            return {
                val: dates[curr],
                date: curr
            };
        } else {
            return prev;
        }
    }, {
        val: 0,
        date: null
    }); }

预期结果测试用例 1:{ val: 0, date: null }

预期结果测试用例 2:{ val: 1, date: '2022-04-29' }

预期结果测试用例 3:{ val: 3, date: '2022-04-28' }

看起来您只需要 sort 个对象的两个参数:

const test1 = {};
const test2 = { '2022-04-29': 1 };
const test3 = { '2022-04-29': 3, '2022-04-30': 2, '2022-04-28': 3, '2022-05-02': 2 };
const test4 = { '2022-04-29': 4, '2022-04-28': 4, '2022-04-30': 4, '2022-05-02': 2 };

  
const getEarliest = (dates) => {
  const [date, val] = Object.entries(dates)
    .sort(([k1, v1], [k2, v2]) => v2 - v1 || Date.parse(k1) - Date.parse(k2) ) 
    .at(0) ?? [null, 0];

  return { val, date };
};

console.log(getEarliest(test1));
console.log(getEarliest(test2));
console.log(getEarliest(test3));
console.log(getEarliest(test4));
.as-console-wrapper {max-height: 100% !important; top: 0}

reduce相同的结果:

const test1 = {};
const test2 = { '2022-04-29': 1 };
const test3 = { '2022-04-29': 3, '2022-04-30': 2, '2022-04-28': 3, '2022-05-02': 2 };
const test4 = { '2022-04-29': 4, '2022-04-28': 4, '2022-04-30': 4, '2022-05-02': 2 };

  
const getEarliest = (dates) => {
  const [date, val] = Object.entries(dates)
    .reduce((prev, curr) => (curr[1] - prev[1] || Date.parse(prev[0]) - Date.parse(curr[0])) > 0  
      ? curr 
      : prev
    , [null, 0]);
  
  return { val, date };
};

console.log(getEarliest(test1));
console.log(getEarliest(test2));
console.log(getEarliest(test3));
console.log(getEarliest(test4));
.as-console-wrapper {max-height: 100%!important;top:0 }

在您的代码中 prev.date 值最初为空。所以 reduce() 将始终 return 初始对象。

试试这个代码,它对你有帮助

 getEarliest = (dates) => {
      if (Object.keys(dates).length > 0) {
        let date = Object.keys(dates).reduce((prev, curr) => {
          if (prev > curr) {
            return curr;
          } else {
            return prev;
          }
        });

        return {
          val: dates[date],
          date: date
        }
      } else {
        return {
          val: 0, date: null
        }
      }
    }

因为你有2个排序条件,所以它们必须按一定的顺序排列。根据您的示例,我假设订单是:“最大价值”->“最小日期”。然后你的 if 会变成下面这样:

getEarliest = (dates) => {
  return Object.keys(dates).reduce(
    (prev, curr) => {
      if (dates[curr] > prev.val || (dates[curr] === prev.val && curr < prev.date)) {
        return {
          val: dates[curr],
          date: curr,
        }
      } else {
        return prev
      }
    },
    {
      val: 0,
      date: null,
    }
  )
}
  • 在第一个语句中,.date 属性 从未定义,因此它应该是 undefineddates 是一个数组而不是对象,所以 dates[curr] 看起来像 dates['2022-04-28'] 这没有用。在符号形式前。 array[5] 一个整数作为 .reduce()

    的第三个参数的索引放在括号中
    if (dates[curr] > prev.date) {...
    
  • 你得到 "2022-04-29" 的原因是因为数组永远不会改变,你需要使用 .sort() 更简单的方法或 .reduce() 对日期进行实际排序对新手来说复杂。

详情在下面的例子中注释

let A = {};

let B = {
  '2022-04-29': 1
};

let C = {
  '2022-04-29': 3,
  '2022-04-30': 2,
  '2022-04-28': 3,
  '2022-05-02': 2
};

// Optional utility function
const log = data => console.log(JSON.stringify(data));

/*
Can convert from timestamp to YYYY-MM-DD and vice versa
*/
const dX = (number, string) => {
  let D;
  if (number) {
    let date = new Date(number);
    D = ` ${date.getFullYear()}-${("0" + (date.getMonth() + 1)).slice(-2)}-${("0" + date.getDate()).slice(-2)}`;
  } else if (string) {
    D = Date.parse(string);
  } else {
    return false;
  }
  return D;
};

// Pass tS = {...}
const getEarliest = tS => {
  // if tS is empty...
  if (Object.keys(tS).length === 0) { // Return premade object
    return {
      val: 0,
      date: null
    };
  }
  /*
  Object.entries(tS) converts {k: v, k: v,...} into [[k,v], [k,v]...]
  */
  /*
  .map(([k, v]) exposes key/value
  pairs by destructuring [k, v]
  */
  /*
  .sort(a, b) is referencing each
  date key and converting it into
  a number (ms since epoch)
  */
  let table = Object.entries(tS).map(([k, v]) => [k, v]).sort((a, b) => dX(null, a[0]) - dX(null, b[0]));
  let obj = {};
  obj.val = table[0][1];
  obj.date = table[0][0];
  return obj;
};

log(getEarliest(A));
log(getEarliest(B));
log(getEarliest(C));