Javascript备忘录查找数组

问题描述 投票:1回答:2

我正在尝试提高有关javascript中记忆的知识。我创建了一个记忆功能(我认为..)

我已经对项目进行了一系列更改(更改日志)。数组中的每个项目都包含对其进行编辑的reference-id(employeeId)。看起来像这样。

const changeLog = [
  {
    id: 1,
    employeeId: 1,
    field: 'someField',
    oldValue: '0',
    newValue: '100',
  },
  {
    id: 2,
    employeeId: 2,
    field: 'anotherField',
    oldValue: '20',
    newValue: '100',
  },
  ...
]

我还有一个包含每个员工的数组,看起来像这样:

const employees = [
    {
        name: 'Joel Abero',
        id: 1
    },
    {
        name: 'John Doe',
        id: 2
    },
    {
        name: 'Dear John',
        id: 3
    }
]

要找到进行更改的员工,我将其映射到changeLog中的每个项目上,并找到employeeId等于employees数组中的id的位置。这两个数组都包含500多个项目,我刚刚粘贴了片段。下面,我粘贴了我的备忘录助手。

1)如何执行测试以查看这两个中运行最快的一个?2)这是使用记忆的正确方法吗?3)使用记忆时有经验法则吗?还是应该尽可能多地使用它?

const employees = [
	{
		name: 'Joel Abero',
		id: 1
	},
	{
		name: 'John Doe',
		id: 2
	},
	{
		name: 'Dear John',
		id: 3
	}
]

const changeLog = [
  {
    id: 1,
    employeeId: 1,
    field: 'someField',
    oldValue: '0',
    newValue: '100',
  },
  {
    id: 2,
    employeeId: 2,
    field: 'anotherField',
    oldValue: '0',
    newValue: '100',
  },
  {
    id: 3,
    employeeId: 3,
    field: 'someField',
    oldValue: '0',
    newValue: '100',
  },
  {
    id: 4,
    employeeId: 3,
    field: 'someField',
    oldValue: '0',
    newValue: '100',
  },
  {
    id: 5,
    employeeId: 3,
    field: 'someField',
    oldValue: '0',
    newValue: '100',
  }
]

function findEditedByEmployee (employeeId) {
  return employees.find(({ id }) => id === employeeId)
}

function editedByWithMemoize () {
  let employeesSavedInMemory = {}
  return function(employeeId) {
    if(employeeId in employeesSavedInMemory) {
      console.log("from memory")
      return employeesSavedInMemory[employeeId]
    }
    console.log("not from memory")
    const findEditedBy = findEditedByEmployee(employeeId)
    employeesSavedInMemory[findEditedBy.id] = {name: findEditedBy.name }
    return findEditedBy
  }
}

const memoizedEmployee = editedByWithMemoize();

// with memoization
const changeLogWithEmployeesMemoized = changeLog.map( log => {
  const employeeName = memoizedEmployee(log.employeeId);
  return {
    ...log,
    employeeName: employeeName.name
  }
})

// without memoization
const changeLogWithEmployees = changeLog.map( log => {
  const editedBy = findEditedByEmployee(log.employeeId);
  return {
    ...log,
    employeeName: editedBy.name
  }
})

console.log('memoized', changeLogWithEmployeesMemoized)
console.log('not memoized', changeLogWithEmployees)
javascript arrays memoization
2个回答
0
投票

我会事先创建一个Map并从地图上获取该对象以进行更新。

如果Map不包含所需的map,则创建一个新对象并将其添加到idemployees中。

map
const
    employees = [{ name: 'Joel Abero', id: 1 }, { name: 'John Doe', id: 2 }, { name: 'Dear John', id: 3 }],
    changeLog = [{ id: 1, employeeId: 1, field: 'someField', oldValue: '0', newValue: '100' }, { id: 2, employeeId: 2, field: 'anotherField', oldValue: '20', newValue: '100' }],
    map = employees.reduce((map, o) => map.set(o.id, o), new Map);

for (const { id, field, newValue } of changeLog) {
    let object = map.get(id);
    if (object) {
        object[field] = newValue;
    } else {
        let temp = { id, [field]: newValue };
        employees.push(temp)
        map.set(id, temp);
    }
}

console.log(employees);

0
投票

我将尝试回答您的每个问题:

1)如何执行测试以查看这两个中运行最快的一个?

最好的方法只是简单的for循环。

2)这是使用记忆的正确方法吗?

我不确定您的意思,但是可以将其视为短期缓存。如果您的备忘录调用包含一个API请求,那么这对于不更改数据非常有用,可以节省大量时间,但是,另一方面,如果数据在短时间内可能发生更改,那么备忘录可能会很糟糕想法,这意味着它很快就会过时。

如果您对此函数进行许多调用,则它可能会消耗内存,具体取决于返回数据的大小,但这取决于实现,而不是“适当的方法”

3)使用备忘录时有经验法则吗?还是应该尽可能多地使用它?

如果您开始使用记忆功能,则应尽可能在任何地方使用它。但是,如前所述,它可以根据返回数据迅速耗尽内存。如果您只调用几次甚至一次调用一个函数,则备忘录几乎没有好处。


关于记忆的最后一点是,如果数据已经是客户端,则建议使用像.as-console-wrapper { max-height: 100% !important; top: 0; }这样的映射绝对是一种更好,更有效的方法。它无需循环每次来查找对象,而是循环一次以将数组转换为对象(或映射),从而使您可以在O(1)时间内访问数据。

总而言之,记忆是一个很棒的工具-尤其是在发出API请求时,

((我还在为此答案添加更多内容)

© www.soinside.com 2019 - 2024. All rights reserved.