【问题标题】:Iterating through specified range within js es6 map遍历js es6 map中的指定范围
【发布时间】:2018-09-13 18:29:22
【问题描述】:

我有一个排序的 JavaScript 映射结构,用于存储基于时间的对象状态。
Map(key:time(inMilli), value: {object attributes})

我需要完成的是能够根据开始时间和结束时间检查地图,以获取所有值的集合,而无需遍历整个地图。

//currently using something like this. But would like to not compare against entire map of times
let map = dataService.getTimeData()//returns map of all objects
let updates = getRange(someTime, someTime);

function getRange(start, stop){
  let foundValues = [];
  //if start is end or after end time
  if(start >== stop)return [start];

  //search map for values
  for([key,value] of map){
    if(key > start && key < stop)foundValues.push(key)
  }  
  return foundValues;
}

【问题讨论】:

  • 我没有使用地图,但你不能只使用map.keys() 并对其进行迭代吗?
  • 是的,但这仍然需要遍历整个地图。我正在寻找的是一种从本质上获取两个索引并且只在我需要的时间进行迭代的方法。
  • 正如我所说,我没有使用过 Map,但根据我对 Maps 的了解,我认为如果不检查整个数组,您将无法完成此操作。跨度>
  • 是的,这是我最初的假设,但我真的希望有人能找到方法哈哈。我确实找到了一个库并发布在允许这样做的解决方案中,并且对于客户端数据存储和检索非常方便。尚未测试性能,但看起来相当不错。

标签: javascript es6-map


【解决方案1】:
function getRange(start, stop){

    let foundValues = [];

    if (start >== stop) return [start];

    for(let [key, value] of map.entries()){
        if (key > start && key < stop) {
            foundValues.push(key);
        } else {
            return foundValues;
        }
    }  
    return foundValues;
}

您只需要在地图中的条目时间超出指定范围(开始和停止)时返回数组,这将停止迭代。

function getRange(start, stop) {

  const currentArray = Array.from(map);

  let foundValues = [];
  let currentMap = currentArray.shift();

  while (currentMap[0] > start && currentMap[0] < stop && currentArray.length) {
    foundValues.push(currentMap[1]);
    currentMap = currentArray.shift();
  }

  return foundValues;

}

使用 while 循环,这不会迭代地图中的所有项目。 这仅在地图已排序时有效。

【讨论】:

  • 这类似于我想出的,但真的不希望将整个地图转换为数组的开销。最终找到了一个名为 jstree 的库,它有一个带有上限和下限函数的 javascript TreeMap,可用于像我需要的那样分割地图。
【解决方案2】:

最终使用 jstreemap 并使用 TreeMap 并迭代其上限和下限函数。这真的很容易,并且会推荐。

let map = new TreeMap();//just wanted to show that this is a TreeMap now
map = dataService.getData();

function getRange(startTime, endTime){
  let from = map.lowerBound(startTime);
  let to = map.upperBound(endTime);
  let it = from;//initialize to first value in iterator
  let foundValues = [];

  //only iterates from first object requested to last. No longer needs to search any unnecessary values. 
  while(!it.equals(to)){
    foundValues.push(it);
    it.next();
  }
  return foundValues();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 2020-02-14
    • 2018-04-07
    • 2017-03-26
    • 1970-01-01
    相关资源
    最近更新 更多