【问题标题】:use array reduce to find max property issue [duplicate]使用数组减少来查找最大属性问题[重复]
【发布时间】:2019-09-14 05:09:29
【问题描述】:

我无法理解使用 array reduce 来查找 max 属性的结果

我正在尝试将节点添加到数组,同时添加我想将 id 添加到节点。 这是测试的示例

localNodes: [
    {id:0, x:20, y:20},
    {id:1, x:50, y:50}
]

addNode(node){
  let maxId = localNodes.reduce( (a, b) => Math.max(a.id, b.id) ); 
  maxId++
  //localNodes.push({id:maxId, ...node})
  localNodes.push({id:maxId, x:node.x, y:node.y})
}

addNode({x:20, y:20})
addNode({x:20, y:20})
addNode({x:20, y:20})

这是奇怪的结果:

  • 数组中添加的节点看起来像“观察者”
  • 第一个添加的节点已正确计算 id = 2
  • 以下所有节点的 id 都设置为 NaN

输出:

localNodes: Array(5)
0: {…}
1: {…}
2: {__ob__: Observer}    -> id = 2
3: {__ob__: Observer}    -> id = NaN
4: {__ob__: Observer}    -> id = NaN

您能否解释一下我做错了什么,并可能指出如何解决它。

【问题讨论】:

  • 你没有返回一个对象......减少代码是错误的

标签: javascript


【解决方案1】:

首先我们看一下reduce function的定义

它接受一个有四个参数的函数

Array​.prototype​.reduce((accumulator, currentValue, currentIndex, array) => {
    // the function must return a value.
    // accumulator: the accumulator accumulates the return value. 
    // currentValue: The current element being processed in the array.
    // currentIndex: The index of the current element being processed in the array. Starts at index 0 if an initialValue is provided and at index 1 otherwise.
    // array: The array reduce() was called upon.  
}, initialValue);

如果您不提供初始值,则累加器将是数组中的第一个元素,而 currentValue 将是数组中的第二个元素


现在第一次运行函数时它会返回 1,因为只有两个值需要检查

翻译成这个

// a = accumulator = {id:0, x:20, y:20}
// b = currentValue= {id:1, x:50, y:50}
Math.max(a.id, b.id) 

这很好,但是当有更多这种情况发生时

第一个周期

// a = accumulator = {id:0, x:20, y:20}
// b = currentValue= {id:1, x:50, y:50}
Math.max(a.id, b.id)  // return 1

第二周期

// a = accumulator = 1 returned from the first cycle
// b = currentValue= {id:2, x:20, y:20}
Math.max(a.id, b.id) // returns NaN because 1.id doesn't makes sense

解决方案

let localNodes = [
    {id:0, x:20, y:20},
    {id:1, x:50, y:50}
]

function addNode(node){
  let maxId = localNodes.reduce( (accumulator, currentValue) => {
    /*
      here we gonna start with 0 which means the accumulator
      will equal 0 at the first cycle and the currentValue
      will be the first element in the array
    */
    Math.max(accumulator,currentValue.id)
  },0); 
  
  maxId++
  localNodes.push({id:maxId, x:node.x, y:node.y})
}

addNode({x:20, y:20})
addNode({x:20, y:20})
addNode({x:20, y:20})

console.log(localNodes)
.as-console-wrapper {
  max-height: 100% !important;
}

【讨论】:

  • 您在 reduce 函数中的解决方案缺少 a.id Math.max(a,b.id) 的“id”。另外值得一提的是,OP 的原始代码在初始化 localNodes 数组时存在语法错误。应该让localNodes = []; 而不是let localNodes : [];
  • 我不认为这是一个错字,它可能是一个类定义,或者 OP 可能来自不同的环境并且忘记更正语法Math.max(a,b.id) 很好,我用更好的方法编辑了答案名称以便您理解。
  • 啊,明白了。感谢您的澄清!
  • @Zohir Salak 非常感谢!
猜你喜欢
  • 2021-12-11
  • 1970-01-01
  • 2015-02-15
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多