【问题标题】:Better way to merge two arrays合并两个数组的更好方法
【发布时间】:2021-06-11 10:42:09
【问题描述】:

我正在尝试让这段代码运行得更实用。

我想根据list 中的名称选择过滤一组数据,然后根据每个人的ReportsTo 递归查找他们的直线经理,但前提是Rank 大于3 .

这可行,但有没有更好更简洁的方法来实现相同的结果?

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

// Start with only these names
const list = ['Fiona', 'Tom']
const filtered = data.filter(({Name}) => list.includes(Name))

// Recursively find the missing managers of the list names if the rank is not below 3
const findManager = (manager) => {
  const next = data.find(({ Name}) => Name === manager)
  return next.Rank > 3
   ? [next, ...findManager(next.ReportsTo)]
   : [next]
}

// Check the line managers for the filtered array and store them
const missingManagers = []
for (const { ReportsTo, Rank} of filtered) {
  if(!list.includes(ReportsTo) && Rank > 3) {
    missingManagers.push(...findManager(ReportsTo))
  }
}

// Merge the missing managers with the filtered list
const result = [...missingManagers, ...filtered]

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

【问题讨论】:

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


    【解决方案1】:

    首先,请注意find 和filter 有不同的用途。

    这有点令人困惑,但如果我理解了,你想提取经理和所有 Rank > 4 的人(经理与否)?

    const data = [
      {
        Name: "Peter",
        ReportsTo: "",
        Rank: 1,
      },
      {
        Name: "Tom",
        ReportsTo: "Peter",
        Rank: 2,
      },
      {
        Name: "Maria",
        ReportsTo: "Tom",
        Rank: 3,
      },
      {
        Name: "Liam",
        ReportsTo: "Maria",
        Rank: 4,
      },
      {
        Name: "John",
        ReportsTo: "Peter",
        Rank: 3,
      },
      {
        Name: "Fiona",
        ReportsTo: "Liam",
        Rank: 5,
      },
    ];
    
    const managers = [];
    
    data.forEach((element) => {
      if (element.ReportsTo && !managers.includes(element.ReportsTo)) {
        managers.push(element.ReportsTo);
      }
    });
    const filtered = data.filter((element) => {
      if (managers.includes(element.Name) || managers.includes(element.ReportsTo) || element.Rank > 3) return element;
      return false;
    });
    
    console.log(filtered);
    
    

    【讨论】:

    • 不,我想做的是代码 sn-p 所做的事情,我只是想知道是否可以不使用 for 循环而只映射过滤器数组
    • 伙计...对不起,但代码是一团糟。你的主要目标是什么?您要过滤哪些元素?需要什么条件?
    【解决方案2】:

    试试这个

    getLineManagersAboveRankThree() {
        return data.filter(person => person.Rank >= 3 &&
                                     data.some(({ReportsTo}) => ReportsTo === person.Name)
                          );
    }
    

    当集合中的任何一个元素满足条件时,方法some 将返回true。因此,您可以在 data 列表中查看某人的直线经理。

    这在时间复杂度方面有点昂贵,但根据要求很简单。

    【讨论】:

      【解决方案3】:

      我找到了这个解决方案,但仍然不确定它是否是更好的方法

      const result = filtered.reduce((total, current) => {
        if(!list.includes(current.ReportsTo) && current.Rank > 3) {
          total.push(
            current,
            ...findManager(current.ReportsTo)
          )
        } else total.push(current)
        
        return total
      
      }, [])
      

      【讨论】:

        猜你喜欢
        • 2020-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-29
        • 2022-01-23
        • 2019-11-29
        • 1970-01-01
        • 2021-07-06
        相关资源
        最近更新 更多