如何从javascript中的对象获取相邻键及其键值?

时间:2018-06-10 03:59:24

标签: javascript javascript-objects

我有这个对象:

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很难用字符串构建变量吗?

5 个答案:

答案 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-1n+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' };