Javascript - 链接到更大数组的值数组
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript - 链接到更大数组的值数组相关的知识,希望对你有一定的参考价值。
我正在使用javascript并创建一个离线应用程序。
我有一个非常大的阵列,超过10mb。我需要从用户进行更改的数组中保存元素,但是将数组写入/读取到磁盘的速度太慢。
我想创建一个仅保存用户所做更改的第二个数组,因此我可以保存该较小的数组,然后当我需要加载更改时,它可以将其更改镜像到大数组。
例如:
lib[x][1][y][6] = "no";
libVars[x][1][y][6] = "no";
libVars将简单地保存lib中的元素更改,并且与大型数组lib的大小不同,因为用户只会与大型数组的一小部分进行交互。
显然这不起作用,因为libVars没有与lib相同的结构,如果它这样做也会占用大量的内存(我想也是如此!)
然后我想循环遍历libVars并在libVars中保存更改的相同元素点更新lib。
有没有办法将一些类型的指针保存到lib中的一个位置,我可以在libVars中存储相关的元素值?
任何帮助将非常感激。
谢谢。
======================
我的大阵列样本
var lib = [
[241,[[221119,"sample data","sample","no","no",131,"no"],
[221121,"sample2 data","sample2","no","no",146,"no"],
[221123,"sample3 data","sample3","no","no",28,"no"],
[221626,"sample4 data","sample4","no","no",26,"no"],
[221628,"sample5 data","sample5","no","no",88,"no"]]],
[330,[[305410,"2sample data","sample 2b","no","no",197,"no"],
[305412,"2sample 2 data","sample2 2b","no","no",147,"no"],
[305414,"3sample 2 data","sample3 2b","no","no",10,"no"] ...
尝试解决Z-Bone发布的解决方案
我添加了tempLib var,但是我没看到你最终如何更新实际的lib对象
Object.entries(libVars).forEach(([path, value]) => {
var tempLib = lib;
var pathParts = path.split('#');
pathParts.forEach((pathPart, index) => {
if (index == pathParts.length-1) {
tempLib[pathPart] = value;
} else {
//I don't fully track what you are doing here.
//I assume you are building the array path, but to me it looks like
// it's getting wiped out and not built upon?
tempLib = tempLib [pathPart];
}
});
});
更新28/01/2019基于nomaam的测试数据
@nomaam请检查以下代码段。我让它改变了lib
数组中的任意路径。我选择的路径是:lib[0][1][3][4]
。您可以看到它最初如何返回值"no"
,然后在执行修改跟踪解决方案后,它返回值"yes"
。
// First Step: Original Data (lib)
var lib = [
[241,[[221119,"sample data","sample","no","no",131,"no"],
[221121,"sample2 data","sample2","no","no",146,"no"],
[221123,"sample3 data","sample3","no","no",28,"no"],
[221626,"sample4 data","sample4","no","no",26,"no"],
[221628,"sample5 data","sample5","no","no",88,"no"]]],
[330,[[305410,"2sample data","sample 2b","no","no",197,"no"],
[305412,"2sample 2 data","sample2 2b","no","no",147,"no"],
[305414,"3sample 2 data","sample3 2b","no","no",10,"no"]]]]
// Log initial value in arbitrary selection lib[0][1][3][4]
console.log(lib[0][1][3][4])
// Second Step: Pointer's object
var libVars = {}
// Example of changing a value via an artificial "pointer" to lib[0][1][3][4]
libVars['0#1#3#4'] = 'yes'; // original value is "no"
// Third Step: Run the modifier - update changes from libVars to lib
Object.entries(libVars).forEach(([path, value]) => {
var tempLib = lib;
var pathParts = path.split('#');
pathParts.forEach((pathPart, index) => {
if (index == pathParts.length - 1) {
tempLib[pathPart] = value;
} else {
tempLib = tempLib[pathPart];
}
});
});
// Log the change fro lib
console.log(lib[0][1][3][4])
更新2
更新了我的答案,摆脱lodash
,它似乎等于Z-Bone
的答案。他的变体比我的更清晰。
更新于@ 28.01.2019
var lib = [
[241,[[221119,"sample data","sample","no","no",131,"no"],
[221121,"sample2 data","sample2","no","no",146,"no"],
[221123,"sample3 data","sample3","no","no",28,"no"],
[221626,"sample4 data","sample4","no","no",26,"no"],
[221628,"sample5 data","sample5","no","no",88,"no"]]],
[330,[[305410,"2sample data","sample 2b","no","no",197,"no"],
[305412,"2sample 2 data","sample2 2b","no","no",147,"no"],
[305414,"3sample 2 data","sample3 2b","no","no",10,"no"]]]];
// object to track edits
var edits = {
'0.1.2.2': 'edited'
};
// sample/simple implementation of lodash's 'set' function
function applyEdit(arr, path, value) {
var items = path.split('.');
var last = items.length - 1;
var current = arr;
items.forEach(function (item, i) {
if (i !== last) {
current = current[item];
}
});
current[items[last]] = value;
}
// our restoration function
function patch(arr, edits) {
Object.keys(edits).forEach(function(key) {
var newValue = edits[key];
applyEdit(arr, key, newValue);
});
}
console.log(lib[0][1][2][2]) // "sample3"
// now we can restore our edits
patch(lib, edits);
console.log(lib[0][1][2][2]) // "edited"
// --------------------------------------------------------
// to prevent forgetting to track the updates you can use utility function
// to make changes to your 'lib' array
function update(arr, path, value) {
applyEdit(arr, path, value);
edits[path] = value;
}
原始答案:
一种可能的解决方案是拥有一个跟踪所有更改的对象。 const edits = {};
当你用lib[x][1][y][6] = "no";
更新你的对象时,你也保存你的编辑:
edits[`${x}.1.${y}.6`] = "no";
基本上,您只需创建一个包含更改路径的字符串。
从文件加载编辑对象后,可以使用以下代码将所有更改应用于原始数组:
import { set } from 'lodash';
function patch(arr, edits) {
Object.keys(edits).forEach(key => {
const newValue = edits[key];
set(arr, key, newValue);
});
}
假设libVars
中lib
中的路径相同,那么您可以简单地将更改记录到稍后在lib
对象上重新应用的函数数组中:
const data = {foo: 'aaa', bar: 'bbb'};
console.log('data before:', data);
const updates = [];
updates.push(obj => {
obj.foo = 'foo';
});
updates.push(obj => {
obj.bar = 'bar';
});
updates.forEach(fn => fn(data));
console.log('data after:', data);
这可以使用代理模拟自动生成来处理。看到:
https://en.wikipedia.org/wiki/Autovivification
Autovivification and Javascript
以上是关于Javascript - 链接到更大数组的值数组的主要内容,如果未能解决你的问题,请参考以下文章