【问题标题】:Reduce recursively pushing only once减少递归推送一次
【发布时间】:2021-06-11 08:52:20
【问题描述】:

我正在尝试在对象数组上递归运行 reduce 方法。

我从一个字符串开始并推送与该字符串匹配的对象,然后我看到那个条目ReportsTo 的对象,一旦我得到那个对象我推送它并继续递归检查那个对象ReportsTo 下一个直到它到达在这种情况下,最大 Rank 为 3。

但它并没有超越第一个。

const data = [
  {
    Name: 'Peter',
    ReportsTo: '',
    Rank: 1
  },
  {
    Name: 'Tom',
    ReportsTo: 'Peter',
    Rank: 2
  },
  {
    Name: 'Maria',
    ReportsTo: 'Tom',
    Rank: 3
  },
  {
    Name: 'John',
    ReportsTo: 'Peter',
    Rank: 3
  },
  {
    Name: 'Fiona',
    ReportsTo: 'Maria',
    Rank: 4
  }
]

const findManager = (person) => data.reduce((total, current) => {
  if (current.Name === person) {
    total.push(current)
    if (current.Rank > 2) {
      findManager(current.ReportsTo)
    }
  }  
  
  return total
}, [])

console.log(findManager('Fiona'))
.as-console-wrapper { max-height: 100% !important; top: 0; }

期望输出将是所有小于 3 且在本例中管理的对象 Fiona

[ 
  { Name: 'Fiona', ReportsTo: 'Maria', Rank: 4 },
  { Name: 'Maria', ReportsTo: 'Tom', Rank: 3 },
  { Name: 'Tom', ReportsTo: 'Peter', Rank: 2 }
]

【问题讨论】:

  • 当您对某个值 (if (...) { findManager(...) }) 不感兴趣时​​,为什么 findManager() 会返回某些值 (return total)?
  • 但是我有兴趣返回下一个,只要Rank 高于 3,我必须在某个时候返回总数,对吧?
  • 那么……为什么不返回总数?
  • 我认为根据回复,我使用了错误的函数来满足我的需要,但出于好奇,只返回总数是什么意思?,我是。
  • 不在if ( ... ) 块中

标签: javascript arrays ecmascript-6 javascript-objects ecmascript-2016


【解决方案1】:

我不认为.reduce 在这里是合适的工具,因为您试图在数组的给定迭代内的数组中找到一个 项。使用.find 或普通循环。然后,您需要使用递归调用的结果 - 解决此问题的一种方法是使用第二个参数,即结果数组,它被传递并推送到:

const data=[{Name:"Peter",ReportsTo:"",Rank:1},{Name:"Tom",ReportsTo:"Peter",Rank:2},{Name:"Maria",ReportsTo:"Tom",Rank:3},{Name:"John",ReportsTo:"Peter",Rank:3},{Name:"Fiona",ReportsTo:"Maria",Rank:4}];

const findManagers = (name, results = []) => {
  const person = data.find(p => p.Name === name);
  results.push(person);
  if (person.Rank > 2) {
    findManagers(person.ReportsTo, results)
  }
  return results;
};
console.log(findManagers('Fiona'))
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 我有一些非常相似的东西,我只是尝试使用 reduce 来返回该数组,但这就是这样做的,谢谢!
【解决方案2】:

我真的不明白在这里使用reduce 有什么意义。 reduce 旨在提供一系列值的组合结果,但您只是在寻找一个值(并使用副作用来完成它)。

我认为这是一个更好的方法:

const findManagers = (name) => {
    const foundPerson = data.find(({ Name }) => Name === name);
    
    return foundPerson.Rank > 2
        ? [foundPerson, ...findManagers(foundPerson.ReportsTo)]
        : [foundPerson];
};

const data = [
  {
    Name: 'Peter',
    ReportsTo: '',
    Rank: 1
  },
  {
    Name: 'Tom',
    ReportsTo: 'Peter',
    Rank: 2
  },
  {
    Name: 'Maria',
    ReportsTo: 'Tom',
    Rank: 3
  },
  {
    Name: 'John',
    ReportsTo: 'Peter',
    Rank: 3
  },
  {
    Name: 'Fiona',
    ReportsTo: 'Maria',
    Rank: 4
  }
]

console.log(findManagers('Fiona'))
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 谢谢,与@CertainPerformance 非常相似,但我真的很喜欢三元组
猜你喜欢
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
相关资源
最近更新 更多