簡體   English   中英

在JavaScript中搜索數組映射的最有效方法

[英]Most efficient way to search a map of arrays in JavaScript

我有一個JavaScript數字數組的地圖。 我的目標是獲取包含特定數字的值的鍵。 我也對可能更有效的不同數據結構持開放態度。

let bookCategory = {
    "fantasy": [10064, 10066, 10071],
    "scifi": [10060, 10037, 10061],
    "history": [10001, 10003, 10004, 10005],
    "biography": [10032, 10006, 10002, 10028, 10009, 10030, 100031],
    "educational": [10025]
};

每個數字只會出現一次,但每個數組可以包含接近一百個數字,並且它可能會從那里大幅增長。 數組可以是不可變的,因為我的數據是靜態的。

現在我有這個,但它看起來效率不高。

let category;
let keys = _.keys(categories);
let theNumber = 10032;

for(let j = 0; j < keys.length; j++) {
    if(_.includes(categories[keys[j]], theNumber)) {
        category = keys[j];
        break;
    }
}

lodash庫有很多有用的功能。 使用它,您有以下選擇:

1.二進制搜索

使用排序的數字數組創建一個新結構。 查找數字時,應用二進制搜索。
_.sortedIndexOf()方法在數組中使用二進制搜索。

var bookCategory = {
 "fantasy": [10064, 10066, 10071],
 "scifi": [10060, 10037, 10061],
 "history": [10001, 10003, 10004, 10005],
 "biography": [10032, 10006, 10002, 10028, 10009, 10030, 100031],
 "educational": [10025]
};

var binaryMap = _.mapValues(bookCategory, function(category) {
  return category.sort(function(num1, num2) { 
    return num1 - num2; 
  });
});

//then search using binary algorithm    
var number = 10032;
var keyForNumber = _.findKey(binaryMap, function(numbers) {
  return _.sortedIndexOf(numbers, number) !== -1;
});

keyForNumber // prints "biography"

檢查工作演示

2.創建一個地圖對象

因為數字只出現一次,所以很容易創建一個大的哈希對象,其中鍵是數字,值是類別。 它需要更多的內存,因為復制類別字符串,但它的工作速度非常快。
該解決方案不需要lodash。

var bookCategory = {
 "fantasy": [10064, 10066, 10071],
 "scifi": [10060, 10037, 10061],
 "history": [10001, 10003, 10004, 10005],
 "biography": [10032, 10006, 10002, 10028, 10009, 10030, 100031],
 "educational": [10025]
};

var map = _.reduce(bookCategory, function(result, numbers, key) {
  _.each(numbers, function(number) {
    result[number] = key;
  });
  return result;
}, {});

// or alternative without lodash
var mapAlternative = Object.keys(bookCategory).reduce(function(result, key) {
  bookCategory[key].forEach(function(number) {
    result[number] = key;
  });
  return result;
}, {});


var number = 10003;
map[number]; // prints "history"

檢查工作演示

有太多的what-ifs要回答這個問題,最大的一個是:多久將是數據updated VS read

如果要更頻繁地read它,那么首先遍歷bookCategory並創建一個稀疏數組/對象,將數字鏈接回類別。

(我會在這里尋找對象):

// Generate this programatticly, of course.
bookCategoryLinkback = {
    10064: "fantasy",
    10066: "fantasy",
    10071: "fantasy"
};

對數組進行排序並使用二進制搜索。 您可以使用lodash lib輕松完成。

我建議使用哈希表來表示數字。

 var bookCategory = { "fantasy": [10064, 10066, 10071], "scifi": [10060, 10037, 10061], "history": [10001, 10003, 10004, 10005], "biography": [10032, 10006, 10002, 10028, 10009, 10030, 100031], "educational": [10025] }, numbers = function (data) { var r = Object.create(null); Object.keys(data).forEach(k => data[k].forEach(a => r[a] = k)); return r; }(bookCategory) document.write('<pre>' + JSON.stringify(numbers, 0, 4) + '</pre>'); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM