繁体   English   中英

根据索引数组从对象中提取特定的javascript值

[英]Pluck specific javascript value from an object based on an array of indexes

给定这样的嵌套对象:

var cars = {
    "bentley": {
        "suppliers": [
            {
            "location": "England",
            "name": "Sheffield Mines"}
        ]
        // ...
    }
};

像这样的数组["bentley", "suppliers", "0", "name"] ,是否存在一个将pluck_innards(cars, ['bentley', "suppliers", "0", "name"])最深元素的现有函数,即pluck_innards(cars, ['bentley', "suppliers", "0", "name"])并返回“ Sheffield Mines”。

换句话说,有一个函数(我将其命名为deep_pluck ),其中

deep_pluck(cars, ['bentley', 'suppliers', '0', 'name']) 
         === cars['bentley']['suppliers']['0']['name']

在我看来,这很简单,但已足够普遍,以至于可以在诸如jQuerylo-dash / underscore之类的Javascript实用程序库中完成-但我没有看到它。

我的想法很琐碎,大致如下:

function deep_pluck(array, identities) {
    var this_id = identities.shift();
    if (identities.length > 0) {
        return deep_pluck(array[this_id], identities);
    }
    return array[this_id];
}

我已经在jsFiddle上发布

如果函数足够智能以识别何时需要数组中的数字索引,那当然会有所帮助。 我不确定还有什么需要注意的地方。

对于我认为已经巧妙解决的问题,这是一个相当长的问题,但是我想将其发布,因为我很想看看那里有什么解决方案。

我不认为如果将数字作为0传递给数组索引,就不会有问题。

这是没有递归的函数的替代版本:

function deep_pluck(object, identities) {
    var result = object;
    for(var i = 0; i < identities.length; i++) {
        result = result[identities[i]];
    }
    return result;
}

此处的工作示例: http : //jsfiddle.net/AmH2w/1/

尽管不是通用库,但CasperJSutils.getPropertyPath函数似乎具有这种类型的东西。

/**
 * Retrieves the value of an Object foreign property using a dot-separated
 * path string.
 *
 * Beware, this function doesn't handle object key names containing a dot.
 *
 * @param  Object  obj   The source object
 * @param  String  path  Dot separated path, eg. "x.y.z"
 */
function getPropertyPath(obj, path) {
    if (!isObject(obj) || !isString(path)) {
        return undefined;
    }
    var value = obj;
    path.split('.').forEach(function(property) {
        if (typeof value === "object" && property in value) {
            value = value[property];
        } else {
            value = undefined;
        }
    });
    return value;
}

编辑:

从那以后,我遇到了几种解决方案,包括:

  1. Ben Alman的getObject插件(在Github上 )。
  2. 我滚了一个-见要点

编辑(2014)

我还要注意相对较新的lodash.deep

dotty.get(obj,pathspec)执行此操作,接受数组或点分字符串作为pathspec。

Dotty是开源的,还具有一个exist方法和一个推杆。

该方法是递归的,并且与您的想法非常相似,不同之处在于dotty包含对null / undefined对象的测试,这样它就不会为尝试访问不存在的元素而引发异常。

来自文档dotty.get()源发布在下面:

var get = module.exports.get = function get(object, path) {
  if (typeof path === "string") {
    path = path.split(".");
  }

  if (!(path instanceof Array) || path.length === 0) {
    return;
  }

  path = path.slice();

  var key = path.shift();

  if (typeof object !== "object" || object === null) {
    return;
  }

  if (path.length === 0) {
    return object[key];
  }

  if (path.length) {
    return get(object[key], path);
  }
};

这是一个使用reduce的简短ES6实现:

function get(obj, keyPath) {
    return keyPath
        .split(".")
        .reduce((prev, curr) => prev[curr], obj);
}

用法:

get(cars, "bentley.suppliers.0.name") // -> "Sheffield Mines"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM