如果在HashMap中未定义元素,则查找上一个元素

时间:2020-06-24 03:11:17

标签: javascript hashmap

我有一个HashMap

const hash = {
  "00:00": "Hello",
  "00:01": "Every one",
  "00:04": "Nice to meet you",
  "00:10": "Could you introduce yourself?",
  "00:23": "Hi, My name is HashMap"
}
console.log(hash["00:00"]);
console.log(hash["00:01"]);
console.log(hash["00:04"]);
console.log(hash["00:05"]); // it returns `undefined`, so it should find previous element. in this case "00:04"
console.log(hash["00:10"]);
console.log(hash["00:17"]); // it also returns `undefined`, it should find "00:10" element.
console.log(hash["00:19"]); // it also should find "00:10" element.
console.log(hash["00:22"]); // it also should find "00:10" element.
console.log(hash["00:23"]); 

预先感谢

已编辑

我不想重复所有元素。因为它对HashMap没有意义。

3 个答案:

答案 0 :(得分:3)

const hash = {
  "00:00": "Hello",
  "00:01": "Every one",
  "00:04": "Nice to meet you",
  "00:10": "Could you introduce yourself?",
  "00:23": "Hi, My name is HashMap"
}


function x(time, check) {
    var prev = -1;
    var i;
    for (i in time) {
        var n = i;
        if ((prev != -1) && (check < n))
            return prev;
        else 
            prev = n;
    }
}

console.log(x(hash, "00:05"));

答案 1 :(得分:2)

您应该可以通过Proxy来度过难关。它允许您截取和重新定义对象上的操作。使用您的示例,它看起来可能像这样:

let hash = {
  "00:00": "Hello",
  "00:01": "Every one",
  "00:04": "Nice to meet you",
  "00:10": "Could you introduce yourself?",
  "00:23": "Hi, My name is HashMap"
}
const handler = {
  // Keeps track of last property accessed
  last: undefined,
  get: function (obj, prop) {
    if (prop in obj) {
      // Exists, so update last accessed property
      this.last = obj[prop];
      return obj[prop];
    }
    // Because there is no matching property, return last accessed
    return this.last;
  }
}
// Implement proxy
hash = new Proxy(hash, handler);

console.log(hash["00:00"]);  // Hello
console.log(hash["00:01"]);  // Every  one
console.log(hash["00:04"]);  // Nice to meet you
console.log(hash["00:05"]);  // Nice to meet you
console.log(hash["00:10"]);  // Could you introduce yourself?
console.log(hash["00:17"]);  // Could you introduce yourself?
console.log(hash["00:19"]);  // Could you introduce yourself?
console.log(hash["00:22"]);  // Could you introduce yourself?
console.log(hash["00:23"]);  // Hi, My name is HashMap

编辑(在澄清问题之后)

要找到最近的前一个属性,没有很多事情要做,并且不涉及至少迭代一些键。此实现使用二进制搜索,但我认为基于O(n)的可能定义,仍将其视为Object.keys()。我把按键撞了一个小时,所以您会看到尝试访问一个小于定义的值的结果。

let hash = {
  "01:00": "Hello",
  "01:01": "Every one",
  "01:04": "Nice to meet you",
  "01:10": "Could you introduce yourself?",
  "01:23": "Hi, My name is HashMap"
}
const handler = {
  get: function (obj, prop) {
    if (obj[prop] !== undefined) {
      return obj[prop];
    } else {
      // Validate input format before bothering to search
      if (/\d{2}:\d{2}/.test(prop) !== true) return undefined;
      
      // Search for nearest previous property
      const keys = Object.keys(obj);
      return obj[findPrevious(keys, prop, 0, keys.length)];
    }
  }
}

function findPrevious(keys, prop, start, end) {
  // No previous key is available, so bail out
  if (start > end) return undefined;
  
  const middle = Math.floor((start + end) / 2);
  const current = keys[middle];
  const next = keys[middle + 1];
  
  // Previous property is found or is the maximum defined
  if (current < prop && (next > prop || next === undefined)) {
    return keys[middle];
  }
  
  // Otherwise, keep searching
  if (keys[middle] > prop) {
    return findPrevious(keys, prop, start, middle - 1);
  } else {
    return findPrevious(keys, prop, middle + 1, end);
  }
}
// Implement proxy
hash = new Proxy(hash, handler);

console.log(hash["00:01"]);  // undefined
console.log(hash["01:00"]);  // Hello
console.log(hash["01:01"]);  // Every  one
console.log(hash["01:04"]);  // Nice to meet you
console.log(hash["01:05"]);  // Nice to meet you
console.log(hash["01:10"]);  // Could you introduce yourself?
console.log(hash["01:17"]);  // Could you introduce yourself?
console.log(hash["01:19"]);  // Could you introduce yourself?
console.log(hash["01:22"]);  // Could you introduce yourself?
console.log(hash["01:23"]);  // Hi, My name is HashMap
console.log(hash["10:00"]);  // Hi, My name is HashMap

如果读取比写入更常见,则可以将Object.keys()的结果存储在处理程序中并在每个插入上进行设置,但这会使所有插入变为O(n)并读取{{1} }。创建代理时,您还需要定义密钥,否则它将只是一个空数组。

答案 2 :(得分:1)

我认为这正是您需要的,您可以从哈希中检索,无需遍历哈希,并且考虑了小时和分钟,因此您可以插入任何小时/分钟

const hash = {
  "00:00": "Hello",
  "00:01": "Every one",
  "00:04": "Nice to meet you",
  "00:10": "Could you introduce yourself?",
  "00:23": "Hi, My name is HashMap"
}


function gethrmin(key){
  ka=key.split(':')
  a=ka[0].charAt(0) ,b=ka[0].charAt(1), c=ka[1].charAt(0), d=ka[1].charAt(1) ,prev=""
  h= a =='0' && b=='0'?0:(a=='0' && b!='0'?parseInt(b):parseInt(ka[0])) 
  m= c =='0' && d=='0'?0:(c=='0' && d!='0'?parseInt(d):parseInt(ka[1]))
}
function prevTi(){
  return h<9&&h!=0 && m==0?prev="0"+`${h-1}`+":"+"59":( h>9 && m==0?prev=`${h-1}`+":"+"59":(h==0 && m==0?prev="23:59":(h==0 && m<9 &&m!=0?prev="00:"+"0"+`${m-1}`:(h==0 && m>9 &&m!=0?prev="00:"+`${m-1}`:(h<9 && h!=0 || m<9&& m!=0 ?prev="0"+h+":"+"0"+`${m-1}`:(h>9 && h!=0 || m>9 && m!=0 ?prev=h+':'+`${m-1}`:(h>9 && h!=0 || m<9 && m!=0 ?prev=h+':'+"0"+":"+`${m-1}`:(h<9 && h!=0 || m>9 && m!=0 ?prev="0"+h+':'+m:null))))))))
 }
function checkdb(key){
  if(!hash[key]){
    gethrmin(key)
    nk=prevTi()
   return checkdb(nk)
}
else
  return hash[key]
}
function _(key){
  if(hash[key]) return hash[key]
    return checkdb(key)

}
console.log(_('00:00'))
console.log(_('00:01'))
console.log(_('00:04'))
console.log(_('00:05'))
console.log(_('00:10'))
console.log(_('00:17'))
console.log(_('00:19'))
console.log(_('00:22'))
console.log(_('22:22'))