【问题标题】:Efficiently Combining Multiple Array Method Transformations in Javascript在 Javascript 中有效地组合多个数组方法转换
【发布时间】:2021-12-31 11:51:53
【问题描述】:

我有一个满足以下条件的工作程序,但我想知道是否有更有效的解决方案。目前,我应用了 4 种不同的 Javascript 数组方法转换,这导致为每个转换返回一个新数组,总共 4 个新数组。可以将这些转换组合以仅创建 1 个附加数组而不是 4 个新数组吗?我可以将调用链接在一起,但我认为可以将它们全部组合到 reduce() 方法中,但我不确定这会是什么样子,或者是否有更好的解决方案。

需要满足的条件:

  1. 仅包括来自 Google 组织的员工,但允许将其作为输入参数传递
  2. 姓氏应该是唯一的(没有重复的姓氏)
  3. 员工应按 ID 排序(升序)
  4. 每个员工都应该有一个名为 fullName 的附加属性,它是名字和姓氏的组合,用空格分隔
const GOOGLE_ORG = 'Google';

const employees = [
  {
    id: 3,
    firstName: 'John',
    lastName: 'Doe',
    organization: 'Google',
  },
  {
    id: 7,
    firstName: 'Jake',
    lastName: 'Smith',
    organization: 'Google',
  },
  {
    id: 1,
    firstName: 'Jane',
    lastName: 'Doe',
    organization: 'Google',
  },
  {
    id: 2,
    firstName: 'Vanessa',
    lastName: 'Smith',
    organization: 'Meta',
  },
  {
    id: 5,
    firstName: 'Sarah',
    lastName: 'Hernandez',
    organization: 'Meta',
  },
  {
    id: 8,
    firstName: 'Jessica',
    lastName: 'Morales',
    organization: 'Google',
  },
  {
    id: 4,
    firstName: 'Paul',
    lastName: 'Stark',
    organization: 'Google',
  },
  {
    id: 6,
    firstName: 'Peter',
    lastName: 'Brown',
    organization: 'Meta',
  },
];

const transformArray = (org) => {
  const filteredByOrg = employees.filter((employee) => employee.organization === org);
  const addedFullName = filteredByOrg.map((employee) => ({
    ...employee,
    fullName: employee.firstName + ' ' + employee.lastName,
  }));
  const uniqueByLastName = [...addedFullName.reduce((map, obj) => map.set(obj.lastName, obj), new Map()).values()];
  return uniqueByLastName.sort((a, b) => a.id - b.id);
};

transformArray(GOOGLE_ORG);

【问题讨论】:

  • 例如,您可以写 map.set(obj.lastName, { ...obj, fullName: obj.firstName + " " + obj.lastName }) 并删除 map,而不是 map.set(obj.lastName, obj)。就个人而言,我更喜欢您的拆分方法,因为它更具可读性,但我会尽可能链接方法调用。您也可以考虑使用Iterator Helpers

标签: javascript node.js arrays


【解决方案1】:

是的,您可以使用Array.prototype.reduce 来最大限度地减少创建数组和迭代次数。

const GOOGLE_ORG = 'Google';

const employees = [
  {
    id: 3,
    firstName: 'John',
    lastName: 'Doe',
    organization: 'Google',
  },
  {
    id: 7,
    firstName: 'Jake',
    lastName: 'Smith',
    organization: 'Google',
  },
  {
    id: 1,
    firstName: 'Jane',
    lastName: 'Doe',
    organization: 'Google',
  },
  {
    id: 2,
    firstName: 'Vanessa',
    lastName: 'Smith',
    organization: 'Meta',
  },
  {
    id: 5,
    firstName: 'Sarah',
    lastName: 'Hernandez',
    organization: 'Meta',
  },
  {
    id: 8,
    firstName: 'Jessica',
    lastName: 'Morales',
    organization: 'Google',
  },
  {
    id: 4,
    firstName: 'Paul',
    lastName: 'Stark',
    organization: 'Google',
  },
  {
    id: 6,
    firstName: 'Peter',
    lastName: 'Brown',
    organization: 'Meta',
  },
];

const transformArray = (org) => {
  return (employees.reduce((lastNames => ((acc, curr) => {
    if(!lastNames.has(curr.lastName) && curr.organization === org) {
        lastNames.add(curr.lastName)
        acc.push({...curr, fullName: `${curr.firstName} ${curr.lastName}`})
    }
    return acc;
  }))(new Set()), []).sort((a, b) => a.id - b.id));
};

console.log(transformArray(GOOGLE_ORG));

【讨论】:

    【解决方案2】:

    您可以链接所有操作。

    实际上它通过过滤唯一的姓氏并在之后排序或通过先排序然后过滤来返回不同的结果。

    closure 的示例:

    将此行用于过滤Set

    .filter((s => ({ lastName }) => !s.has(lastName) && s.add(lastName))(new Set))
    

    闭包将变量带入调用函数的作用域并返回另一个函数。这个函数可以访问变量。 让我们看看不同的格式:

    .filter(
        (s => ({ lastName }) => !s.has(lastName) && s.add(lastName))
        (new Set)
    )
    

    这里用new Set调用函数并返回这个函数

              ({ lastName }) => !s.has(lastName) && s.add(lastName)
    

    作为过滤器方法的回调。

    const
        GOOGLE_ORG = 'Google',
        employees = [{ id: 3, firstName: 'John', lastName: 'Doe', organization: 'Google' }, { id: 7, firstName: 'Jake', lastName: 'Smith', organization: 'Google' }, { id: 1, firstName: 'Jane',  lastName: 'Doe', organization: 'Google' }, { id: 2, firstName: 'Vanessa', lastName: 'Smith', organization: 'Meta' }, { id: 5, firstName: 'Sarah', lastName: 'Hernandez', organization: 'Meta' }, { id: 8, firstName: 'Jessica', lastName: 'Morales', organization: 'Google' }, { id: 4, firstName: 'Paul', lastName: 'Stark', organization: 'Google' }, { id: 6, firstName: 'Peter', lastName: 'Brown', organization: 'Meta' }],
        result = employees
            .filter(({ organization }) => organization === GOOGLE_ORG)
            .filter((s => ({ lastName }) => !s.has(lastName) && s.add(lastName))(new Set))
            .sort((a, b) => a.id - b.id)
            .map(o => ({ ...o, fullName: o.firstName + o.lastName }));
            
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 你能解释一下第二个过滤器到底发生了什么吗?".filter((s => ({ lastName }) => !s.has(lastName) && s.add(lastName))(新集))”?集合是如何创建的?我通常会看到带有一个返回箭头功能而不是两个的过滤器。我很好奇“s”变量如何变成“new Set()”以用于第二个箭头函数。
    • 请参阅编辑。
    猜你喜欢
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2013-02-13
    相关资源
    最近更新 更多