我正在开发一些使用处理程序在localStorage
中读取/写入信息的软件。您可以在这里找到一个有效的示例:http://jsbin.com/wifucugoko/edit?js,console
我的问题在于下面的代码段(关注switch语句):
_t.set = function(path, value) { // Update a single value or object
if (~path.indexOf(".")) {
let o = path.split(".")[0],
p = this.get(o),
q = path.split(".").slice(1);
switch (q.length) {
// There has to be a better way to do this...
case 1:
p[q[0]] = value;
break;
case 2:
p[q[0]][q[1]] = value;
break;
case 3:
p[q[0]][q[1]][q[2]] = value;
break;
case 4:
p[q[0]][q[1]][q[2]][q[3]] = value;
break;
case 5:
p[q[0]][q[1]][q[2]][q[3]][q[4]] = value;
break;
case 6:
p[q[0]][q[1]][q[2]][q[3]][q[4]][q[5]] = value;
break;
default:
return "error";
}
b.setItem(o, JSON.stringify(p));
return p;
} else {
b.setItem(path, JSON.stringify(value));
return this.get(path);
}
};
我不会成为使用此代码库的唯一人,并且我正在尝试使其他人更容易更新可以放置在localStorage
中的任何值。现在,您可以使用local.set('item.subitem.proeprty', 'value')
之类的值来更新值。尽管上面的代码可以做到这一点,但它很丑陋且无法扩展。
如何改进此方法,以(1)自动更新嵌套在任意深度的属性,而不是编写无限长的switch语句,以及(2)不在父对象上加上{ {1}}值更新后?
该问题与我对[object Object]
的使用无关。我最初将此问题发布在代码审查中,这需要一个有效的上下文示例。他们立即解决了这个问题,因为部分问题是,一旦您开始处理嵌套超过六个对象的值,我提供的代码将无法正常工作。尽管我可以无限期地继续我的switch语句,但这正是我要避免的。
在提供了三个示例后,您将看到在一个位置设置值不会删除其他位置的值:
localStorage
所有这些值,尽管是在不同的时间设置的,但只能更新或创建一个值,而不会清除其他任何先前存在的值。
答案 0 :(得分:1)
对我来说,最小优化如下:
if (~path.indexOf(".")) {
let o = path.split(".")[0],
p = this.get(o),
q = path.split(".").slice(1),
dist = p;
q.forEach(function(item, index) {
if (index < q.length - 1) {
dist = dist[item];
} else {
dist[item] = value;
}
});
b.setItem(o, JSON.stringify(p));
return p;
} else {
更改的部分:
答案 1 :(得分:0)
您可以尝试这样的操作,如果路径不存在,则值为null:
function retreiveValueFromObject(path, object) {
var pathList = path.split(".");
var currentValue = object;
var brokeEarly = false;
for (var i = 0; i < pathList.length; i++) {
if (currentValue[pathList[i]]) {
currentValue = currentValue[pathList[i]];
} else {
brokeEarly = true;
break;
}
}
return {
value: currentValue,
brokeEarly: brokeEarly
};
}
function setValueInObject(path, value, object) {
var nestedObj = retreiveValueFromObject(path, object).value;
var pathList = path.split(".");
var finalKey = pathList[pathList.length - 1];
nestedObj[finalKey] = value;
}
var someObject = {
a: {
c: {
d: "value"
},
z: "c"
},
b: {
f: {
x: "world"
},
g: "hello"
},
};
console.log(retreiveValueFromObject("b.f.x", someObject));
setValueInObject("b.f.y", "newValue", someObject);
console.log(someObject);
答案 2 :(得分:0)
您要查找的是一点递归,我刚刚实现了update方法。
let localStorageHandler = function() {
let b = window.localStorage,
_t = this;
_t.get = function(a) {
try {
return JSON.parse(b.getItem(a))
} catch (c) {
return b.getItem(a)
}
};
function descendAndUpdate(obj, path, value) {
let current = path[0],
remainingPath = path.slice(1);
// found and update
if (obj.hasOwnProperty(current) && remainingPath.length === 0) {
obj[current] = value;
// found but still not there
} else if (obj.hasOwnProperty(current)) {
return descendAndUpdate(obj[current], remainingPath, value);
}
// if you want do add new properties use:
// obj[current] = value;
// in the else clause
else {
throw('can not update unknown property');
}
}
_t.set = function(path, value) { // Update a single value or object
if (~path.indexOf(".")) {
let o = path.split(".")[0],
p = this.get(o),
q = path.split(".").slice(1);
descendAndUpdate(p, q, value);
console.log(p);
b.setItem(o, JSON.stringify(p));
return p;
} else {
b.setItem(path, JSON.stringify(value));
return this.get(path);
}
};
_t.remove = function(a) { // removes a single object from localstorage
let c = !1;
a = "number" === typeof a ? this.key(a) : a;
a in b && (c = !0, b.removeItem(a));
return c
};
};
let local = new localStorageHandler();
// Create user and session info if it doesn't exist
let blankUser = new Object({
alias: '',
dob: '',
PIN: '',
level: 0,
name: {
first: '',
last: '',
mi:'',
},
session: {
token: '',
timeout: true,
lastChange: Date.now()
}
});
local.remove('user');
// Loads user data into localstorage
if (!local.get('user')) {
local.set('user', blankUser);
}
local.set('user.session.timeout', false);
local.set('user.name', {first:'john', last:'doe', mi:'c'});
local.set('user.PIN', 8675309);
// new property
// local.set('user.sunshine', { 'like': 'always' });
console.log(local.get('user'));
我的一个朋友总是喜欢堆栈而不是递归,这是第二种选择。无论如何,我同意这里的许多评论。您已经知道您的域模型。除非您有很好的理由使用此方法,否则请花更多时间对数据库中的这些对象进行序列化和反序列化。我的印象是,您将能够以一种更自然的方式处理数据,因为更新数据库中字段的方面将被抽象化。
答案 3 :(得分:0)
我目前正在从事类似的项目。我正在做的是将数据存储在我称为WordMatrix(https://github.com/SamM/Rephrase/blob/master/WordMatrix.js)的东西中,也许您可以在解决方案中使用类似的东西。
我的项目是一个WIP,但下一步实际上是添加对localStorage的支持。该项目本身是一个数据库编辑器,可与键=>值存储区一起使用。您可以在此处查看其原型:(https://samm.github.io/Rephrase/editor.html)
一旦实现了localStorage方面,我将更新这篇文章。
答案 4 :(得分:0)
您的主题让我想起了最近的another topic。
为增强我提供的answer,我向您建议这些功能:
// Function to get a nested element:
function obj_get_path(obj, path) {
return path.split('.').reduce((accu, val) => accu[val] || 'Not found', obj);
}
// Function to set a nested element:
function obj_set_path(obj, path, value) {
var result = obj;
var paths = path.split('.');
var len = paths.length;
for (var i = 0; i < len - 1; i++) {
result = result[paths[i]] || {};
}
result[paths[len - 1]] = value;
return obj;
}
// Example object
var obj = {
name0: 'A name',
level0: {
name1: 'An other name',
level1: {
level2: {
name3: 'Name to be changed',
text3: 'Some other text'
}
}
}
}
// Use of the function
obj = obj_set_path(obj, 'level0.level1.level2.name3', 'Takit Isy');
obj = obj_set_path(obj, 'level0.level1.level2.new3', 'I’m a new element!');
var obj_level2 = obj_get_path(obj, 'level0.level1.level2');
// Consoling
console.log('Consoling of obj_level2:\n', obj_level2);
console.log('\nConsoling of full obj:\n', obj); // To see that the object is correct
⋅ ⋅ ⋅
我们也可以在上面的代码段中改编第二个函数,以便它同时用于get和set,具体取决于是否设置了“ value”:
// We could also adapt the second function for both uses:
function obj_path(obj, path, value = null) {
var result = obj;
var paths = path.split('.');
var len = paths.length;
for (var i = 0; i < len - 1; i++) {
result = result[paths[i]] || {};
}
// Return result if there is no set value
if (value === null) return result[paths[len - 1]];
// Set value and return
result[paths[len - 1]] = value;
return obj;
}
// Example object
var obj = {
name0: 'A name',
level0: {
name1: 'An other name',
level1: {
level2: {
name3: 'Name to be changed',
text3: 'Some other text'
}
}
}
}
// Use of the function
obj = obj_path(obj, 'level0.level1.level2.name3', 'Takit Isy');
obj = obj_path(obj, 'level0.level1.level2.new3', 'I’m a new element!');
var obj_level2 = obj_path(obj, 'level0.level1.level2');
// Consoling
console.log('Consoling of obj_level2:\n', obj_level2);
console.log('\nConsoling of full obj:\n', obj); // To see that the object is correct
希望有帮助。
答案 5 :(得分:0)
怎么样:
SELECT TOP 10 *
FROM Rates
WHERE cast(Date as date)= '2017-06-09'