我有这个对象:
var registered_screens = {
handle_1 : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
这就是我试图让邻居的事情:
function get_neighbors( current_step ) {
var steps = {
next: '',
previous: ''
};
for( var i in registered_screens ) {
if( current_step == registered_screens[i] ) {
if(registered_screens.hasOwnProperty(registered_screens[i])) {
steps.next = registered_screens[i+1];
}
if(registered_screens.hasOwnProperty(registered_screens[i-1])) {
steps.previous = registered_screens[i-1];
}
}
}
return steps;
}
显然,这是不可取的,因为对象不能像数组一样进行解析,只是想展示我尝试过的东西。
我想要获得的是,如果我致电get_neighbors('handle_2')
,请返回:
steps { prev : 'handle_1' , next : 'handle_3' }
或者,对于get_neighbors('handle_3')
:
steps { prev : 'handle_2', next : null }
我也尝试过:
var registered_screens = {
handle_one : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
var key_values = Object.keys(registered_screens);
for( var i = 0; i < key_values.length; i++ ) {
console.log(registered_screens.key_values[i]);
}
但是这引发了:
main.js?ver=4.9.6:18 Uncaught TypeError: Cannot read property '0' of undefined
main.js?ver=4.9.6:18
main.js?ver=4.9.6:270
有趣的是,我检查了key_values[i]
的值是什么,他们是正确的句柄。
似乎JS很难用字符串构建变量吗?
答案 0 :(得分:1)
您的第二次尝试也是我的想法,如果您更正下面的密钥访问,它应该可以正常工作
var registered_screens = {
handle_one : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
var key_values = Object.keys(registered_screens);
for( var i = 0; i < key_values.length; i++ ) {
console.log(registered_screens[key_values[i]]);
}
据我所知,对象中的键是无序的,我们不应该像其他人提到的那样依赖于那个顺序,它的顺序与创建时的顺序不一样,但是你的要求似乎是这样的可以使用Object.keys来迭代并在某种程度上查找next和prev键
对于你的问题,为什么这个registered_screens [key_values [i]]工作而不是registered_screens.key_values [i],点符号对动态键不起作用,即key_values [i]不是键,它是变量持有在这种情况下,您必须像对象[keyNameHolder]
这样的数组访问它答案 1 :(得分:1)
我不喜欢它,并会查看重组以使registered_screens
成为一个数组。由于object order can not be guaranteed,我也不相信这段代码。
也就是说,这将适用于我的浏览器。
编辑:添加了一个数组版本,我相信它会扩展为空白(undefined
)结果。
// array version
var aScreens = [];
aScreens['handle_one'] = 'step_1';
aScreens['handle_2'] = 'step_2';
aScreens['handle_3'] = 'step_3';
function getArrayPrevNext(a,current) {
var x,p = '',n = '',found = false;
for(x in a) {
if (found) {
n = x;
break;
} else if (x == current) {
found = true;
} else {
p = x;
}
}
return {prev:p,next:n};
}
var aSteps = getArrayPrevNext(aScreens,'handle_3');
console.log('array prev['+ aSteps.prev +'], next['+ aSteps.next +']');
var p = aSteps.prev, n = aSteps.next;
console.log('handle prev['+ aScreens[p] +'], next['+ aScreens[n] +']');
console.log('handle alt prev['+ aScreens[aSteps.prev] +'], next['+ aScreens[aSteps.next] +']');
// Object version
var registered_screens = {
handle_one : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
function getPreviousNext(obj,current) {
var prev = '', nxt = '', found = false;
Object.keys(obj).forEach(function(key) {
if (! nxt) {
if (found) {
nxt = key;
} else if (key == current) {
found = true;
} else {
prev = key;
}
}
});
return {prev:prev,next:nxt};
}
var steps = getPreviousNext(registered_screens,'handle_3');
console.log('Object steps:['+ steps.prev +']['+ steps.next +']');
答案 2 :(得分:1)
这个脚本对对象键进行了非常基本的解析 - 它假定它始终采用handle_{n}
的格式 - 基于它创建了一个数组,该数组以正确的顺序保存键,然后搜索和使用n-1
和n+1
返回prev和next(如果可能,返回null
)。是的,我知道,大多数浏览器都会正确排序,所以在大多数情况下你会得到正确的顺序(包括一个控制台输出用于比较)
var screens = {
handle_1 : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3',
handle_4 : 'step_4',
handle_5 : 'step_5',
handle_6 : 'step_6',
handle_7 : 'step_7',
handle_8 : 'step_8',
handle_9 : 'step_9',
handle_10 : 'step_10',
handle_11 : 'step_11',
},
keyParser = (key) => parseInt(key.replace('handle_', '')),
keySorter = (a, b) => keyParser(a) - keyParser(b),
handleKeys = Object.keys(screens).sort(keySorter);
// Compare key ordering in your browser
// It will be most likely identic, since most modern browsers understand that
// it should sort by {str}_{int} and not by {str}_{str} if an {int} is present
// but chances are that for instance IE9 would do the latter, so it could be that
// with browser ordering handle_10 and handle_11 come after handle_1
console.log('browser ordering:', Object.keys(screens));
console.log('parsed ordering:', handleKeys);
function getSteps(handle) {
var pos = handleKeys.indexOf(handle);
if(pos === -1) throw(`Can't find handle ${handle} in screens`);
return {
current: screens[handleKeys[pos]],
prev: pos > 0 ? screens[handleKeys[pos-1]] : null,
next: pos < handleKeys.length-1 ? screens[handleKeys[pos+1]] : null
}
}
console.log(
getSteps('handle_1'),
getSteps('handle_2'),
getSteps('handle_6'),
getSteps('handle_10'),
getSteps('handle_11')
);
同样好的阅读:https://hackernoon.com/out-of-order-keys-in-es6-objects-d5cede7dc92e
答案 3 :(得分:0)
据我所知,答案是没有直接的方法,但你可以通过多种方式解决这个问题。
一个想法是,您可以使用数据的命名约定,例如,
将对象项称为handle_1
而不是&#34; handle_one&#34;等等
你可以使用索引['handle_' + i]
循环遍历数组,但请注意你不能['handle_' + i + 1]
,否则你的索引值会有错误,因为字符串转换将在求和之前发生。
我希望这会有所帮助。
答案 4 :(得分:0)
我做了这个工作:
var registered_screens = {
handle_1 : 'step_1',
handle_2 : 'step_2',
handle_3 : 'step_3'
};
function get_neighbors( current_step ) {
var steps = {
next: '',
previous: ''
};
var key_values = Object.keys(registered_screens);
for( var i = 0; i < key_values.length; i++ ) {
if( current_step == registered_screens[key_values[i]]) {
if( !(registered_screens[key_values[i-1]] == null) ) {
steps.previous = registered_screens[key_values[i-1]];
}
if( !(registered_screens[key_values[i+1]] == null) ) {
steps.next = registered_screens[key_values[i+1]];
}
}
}
return steps;
}
所以,get_neighbors('step_2')
可靠地(在我的测试中)返回:
steps : { next : 'step_3', previous: 'step_1' };