簡體   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