构建哈希表以存储客户名称-Javascript

时间:2018-11-28 23:34:19

标签: javascript linked-list

构建一个系统,允许销售助理输入客户的姓名,  地址和电话号码输入系统,并使用他们的客户来查找客户  电话号码。  将此信息存储在哈希表中。

const hashTable = () => {
   this.customer = name;
   this.address  = address;
   this.number   = number;
} 

我想我不了解哈希表,它们类似于对象,但是它们可以容纳任何数据类型?

2 个答案:

答案 0 :(得分:2)

考虑到您的客户数据存储在如下对象中:

customerData = {
  customer : 'John Smith',
  address : '1 Way ...',
  number : '0604....',
} 

如果您只想使用一种简单的方法来存储客户并使用其号码查找客户,则可以使用一个对象:

const hashTable = {}

const addCustomer = customerData => {
  hashTable[customerData.number] = customerData
}

const searchCustomer = customerNumber => {
  return hashTable[customerNumber]
}

const removeCustomer = customerNumber => {
  hashTable[customerNumber] = null
}

生成的对象将类似于:

hashTable = {
  '0604....' : {
    customer : 'John Smith',
    address : '1 Way ...',
    number : '0604....',
  },
  '0702....' : {
    customer : 'Michel Doe',
    address : '2 Street ...',
    number : '0702....',
  },
}

这里的权衡是:

  • 您不能有多个具有相同编号的客户,hashTable[customerNumber]只能“持有”一个客户参考。但是为什么两个客户会有相同的号码...
  • 也许您不希望数字重复:通过此实现,数字是关键,并且也存储在每个客户数据引用中。顺便说一句,如果您没有成千上万的客户,这将是一个小问题。
  • 如果您再次与成千上万的客户一起工作,则会带来其他非常小的性能和内存问题

答案 1 :(得分:1)

通常,当人们谈论哈希表时,他们谈论的是查找事物。哈希表的妙处在于,您可以通过键查找内容,因此查找值为O(1)。

因此,在您的示例中,我们想要一个充满客户对象的哈希表。预期的输出应类似于:

customer_list = {
  "(123) 456-7890": {
    "name": "Fred Jones",
    "email": "fred@email.com",
    "phone": "(123) 456-7890"
  },
  "(223) 456-7890": {
    "name": "John James",
    "email": "john@email.com",
    "phone": "(223) 456-7890"
  },
  "(323) 456-7890": {
    "name": "Jim Bob",
    "email": "jim@email.com",
    "phone": "(323) 456-7890"
  }
}

因此,我们可以使用customer_list["(323) 456-7890"]通过吉姆·鲍勃(Jim Bob)通过他们的电话号码查找并获得:

{
  "name": "Jim Bob",
  "email": "jim@email.com",
  "phone": "(323) 456-7890"
}

现在,为了使操作更简单,我们可以创建一个Customer类,该类将处理客户对象的创建并处理无效数据,并且可以扩展Map来实现{{1} },以确保所设置的元素是Map#set

的实例

Customer
class Customer {
  constructor({ name = "", email = "", phone = "" }) {
    if (name !== "" || email !== "" || phone !== "") {
      this.name = name
      this.email = email
      this.phone = phone
    } else {
      throw new Error('All fields must be filled')
    }
  }
}

class CustomerList extends Map {
  add(customer) {
    if(customer instanceof Customer) {
      return super.set(customer.phone, customer)
    } else {
      throw new TypeError('Argument `customer` must be a instance of Customer')
    }
  }
  set(phone, customer) {
    if(customer instanceof Customer) {
      return super.set(phone, customer)
    } else {
      throw new TypeError('Argument `customer` must be a instance of Customer')
    }
  }
}

const customer_list = new CustomerList()

const customer_inputs = [
  { 
    name: 'Fred Jones',
    email: 'fred@email.com',
    phone: '(123) 456-7890'
  },
  { 
    name: 'John James',
    email: 'john@email.com',
    phone: '(223) 456-7890'
  },
  { 
    name: 'Jim Bob',
    email: 'jim@email.com',
    phone: '(323) 456-7890'
  }
]

for(let input of customer_inputs) {
  const customer = new Customer(input)
  customer_list.add(customer)
}

function handleCustomerInputSubmit(event) {
  event.preventDefault()
  const data = new FormData(event.target)
  const hash = {}
  for(let key of data.keys()) hash[key] = data.get(key)
  try {
    const customer = new Customer(hash)
    customer_list.add(customer)
    alert('Added Customer')
    event.target.reset()
  } catch(error) {
    alert(error)
  }
}

let output_element = null

function handleCustomerSearchSubmit(event) {
  event.preventDefault()
  const data = new FormData(event.target)
  const phone = data.get('phone')
  const customer = customer_list.get(phone)
  if(customer) {
    output_element.innerHTML = `
      <label>
          <span class="label-text">Name:</span>
          <input type="text" name="name" value="${ customer.name }" readonly>
      </label>
      <label>
          <span class="label-text">Email:</span>
          <input type="text" name="email" value="${ customer.email }" readonly>
      </label>
      <label>
          <span class="label-text">Phone:</span>
          <input type="text" name="phone" value="${ customer.phone }" readonly>
      </label>
    `
  } else {
    output_element.innerHTML = `
      <div class="error">No customer found</div>
    ` 
  }
}

function handleDOMLoad(event) {
  const forms = {}
  
  const customer_input = document.querySelector('#customer-input')
  customer_input.addEventListener('submit', handleCustomerInputSubmit, true)
  
  const customer_search = document.querySelector('#customer-search')
  customer_search.addEventListener('submit', handleCustomerSearchSubmit, true)
  
  output_element = customer_search.querySelector('.output')
}

document.addEventListener('DOMContentLoaded', handleDOMLoad)
* {
  margin: 0;
  line-height: 1.75em;
  font-family: sans-serif;
}

form#customer-input,
form#customer-search {
  display: flex;
  flex-flow: column nowrap;
  flex-grow: 1;
  padding: 5px;
}
form#customer-input label,
form#customer-search label {
  display: flex;
  flex-flow: row nowrap;
  padding: 5px;
}
form#customer-input label span.label-text,
form#customer-search label span.label-text {
  flex: 0 0 auto;
  width: 100px;
  display: inline-flex;
}
form#customer-input label input,
form#customer-search label input {
  flex: 1 0 0;
  min-width: 0;
  max-width: 100%;
}
form#customer-input > button,
form#customer-search > button {
  margin: 5px;
}

form#customer-search .output .error {
  margin: 5px;
  padding: 5px;
  border: 1px solid red;
  color: red;
}