“Object.Key”使用地图搜索

时间:2017-01-04 08:37:18

标签: javascript

老实说,我不知道如何在标题中解释这一点,但我尽我所能。我想要做的是从字符串中获取所有对象/值。但是,由于我的对象可以包含对象,我想确保它也可以。这就是我想要实现的目标:

var key = "House.Number";
var data = "...";
var output = data.map(item => item[key]);

这应该做的是给我所有的门牌号码。简单地执行item["House.Number"]将无效,但如果我执行item["House"]["Number"]它就可以正常工作。这样做有快速/好的方法吗?像.上的拆分之类的东西意味着新对象或类似的东西?

https://jsfiddle.net/psz4Ltqa/1/

4 个答案:

答案 0 :(得分:2)

您可以拆分为路径并循环键,如下所示:

var data = {
  One: {
    Two: {
      Three: 3
    }
  }
}

var getPath = function(obj, path) {
  return path
    .split(".") // Create an array of keys
    .reduce(function(pos, k) {
      return pos.hasOwnProperty(k) ? pos[k] : pos; // Return nested value or, if there isn't, last value
    }, obj);
}

console.log(getPath(data, "One.Two"));
console.log(getPath(data, "One.Two.Three"));

(请注意,您可以自行决定在路径丢失时您想要做什么。例如,您可以返回undefined,或者像我选择的那样,返回您可以找到的最后一个值)

现在,您可以在map操作中使用它,如下所示:

// Switched the argument order to make it more suitable for `map` (data last)
var getPath = function(path, obj) {
  return path
    .split(".") // Create an array of keys
    .reduce(function(pos, k) {
      return pos.hasOwnProperty(k) ? pos[k] : pos; // Return nested value or, if there isn't, last value
    }, obj);
};

var testData = [
  { One: { Two: { Three: "Three" } } },
  { One: { Two: { Three: 3 } } },
  { One: { Two: { Three: "11" } } }
];

var oneTwoThrees = testData.map(getPath.bind(null, "One.Two.Three"));

console.log(oneTwoThrees);

如果您不喜欢绑定语法,可以使用该函数:

// getPath now returns a function that wraps the path in its closure and waits for the object to get its data from
var getPath = function(path) {
  return function(obj) {
    return path
      .split(".") // Create an array of keys
      .reduce(function(pos, k) {
        return pos.hasOwnProperty(k) ? pos[k] : pos; // Return nested value or, if there isn't, last value
      }, obj);
  };
};

var testData = [
  { One: { Two: { Three: "Three" } } },
  { One: { Two: { Three: 3 } } },
  { One: { Two: { Three: "11" } } }
];

var oneTwoThrees = testData.map(getPath("One.Two.Three"));

console.log(oneTwoThrees);

答案 1 :(得分:2)

根据您的要求:

  

这应该做的是给我所有的门牌号码。

使用常规for循环和String.prototype.split()函数的简单解决方案:

...
var output = data.map(function(item){
    var path = key.split('.'), val = {};
    for (var i = 0, len = path.length; i < len; i++) {
        val = val[path[i]] || item[path[i]]; 
    }
    return val;
});

console.log(output); // all house numbers

输出:

[1, 2, 3, 4]

https://jsfiddle.net/psz4Ltqa/3/

答案 2 :(得分:1)

所以基本上你需要这个:

data.map(item => item["House"]["Number"])

但是你希望用给定的key来实现它。你可以这样做:

var keys = key.split('.'), output = data;

for (var i = 0; i < keys.length; i++) {
    output = output.map(item => item[keys[i]]);
}

console.log(output);

答案 3 :(得分:0)

你需要这样的东西。 我在我的项目中使用此功能,效果很好。

  function nestedValue (obj, key) {
    var tmp = obj;
    var keys = key.split('.');
    for(var i = 0; i < keys.length && tmp; i ++) 
      tmp = tmp[keys[i]];

    return tmp;
  }

然后在地图中使用它。

    var output = data.map(item => nestedValue(item, key));