簡體   English   中英

從對象數組獲取鍵值數組,而又不知道對象數組的格式(Javascript)?

[英]Get array of key-values from array of objects without knowing format of array of objects (Javascript)?

想象一下,我給了類似對象數組的引用,例如array將是該array的名稱。 現在,我被要求創建一個數組,該數組包含在該數組的每個對象內找到的某個屬性的所有值,例如"user.id"

問題是我不知道每個對象的格式以及該屬性的駐留位置/嵌套位置。因此"user.id"可能駐留在array[#].someKeyarray[#].someKey["user.id"] )或在array[#].someKey.someOtherKeyarray[#].someKey.someOtherKey["user.id"] )中

是否有可以創建此類數組的函數(jQuery,下划線..etc)? 例如var arrayOfUserIds = returnArray(array, "user.id");

例如,假設以下是此類數組的示例:

var array = [
{
  "age": "13",
  "type": "publish_action",
  "tag": null,
  "timestamp": 1398931707000,
  "content": {
    "action": "publish",
    "user.id": "860",
    "user.email": "alex@somemail.com",
    "property.id": "2149",
    "iteration_id": "15427",
    "test_id": "6063",
    "property.name" : "bloop"
}, {
  ....
}, {
  ....
}];

基於以上所述,我顯然可以做到:

var arrayOfUserIds = [];

for (var i=0; i<array.length; i++)
{
  arrayOfUserIds.push(array[i]["content"]["user.id"]);
}

但是就像我說的那樣,就我而言,我不知道對象的格式,因此無法創建這樣的for循環。

任何想法將不勝感激!

謝謝!

如果我理解正確的話, someArray每個對象要么包含一個屬性user.id要么包含一個包含user.id的對象……或者遞歸地,某個對象包含someArray 您要創建一個僅包含user.id屬性的數組。

一種簡單的方法是對數組中的每個對象進行遞歸檢查,直到找到user.id

// get `user.id` property from an object, or sub-object
// it is assumed that there will only be one such property;
// if there are more than one, only the first one will be returned
function getUserId(o){
    if(o===null || o===undefined) return;
    if(o['user.id']) return o['user.id'];
    for(var p in o){
        if(!o.hasOwnProperty(p)) continue;
        if(typeof o[p] !== 'object') continue;
        if(o[p] === null || o[p] === undefined) continue;
        var id = getUserId(o[p]);
        if(id) return id;
    }
}

function getUserIds(arr){
    return arr.map(function(e){
        return getUserId(e);
    });
}

如果您想要一些通用的東西,可以編寫“ find”方法,該方法將在對象樹中找到命名屬性的所有實例:

 var find = (function(){
    function find(matches, o, prop, checkPrototypeChain){
        if(typeof o[prop] !== 'undefined') matches.push(o[prop]);
        for(var p in o){
            if(checkPrototypeChain || !o.hasOwnProperty(p)) continue;
            if(typeof o[p] !== 'object') continue;
            if(o[p] === null || o[p] === undefined) continue;
            find(matches, o[p], prop, checkPrototypeChain);
        }
    }
    return function(o, prop, checkPrototypeChain){
        var matches = [];
        find(matches, o, prop, checkPrototypeChain);
        return matches;
    }
})();

然后,您可以基於此映射數組:

var userIds = someArray.map(function(e){ return find(e, 'user.id'); });

請注意,我要介紹原型鏈中可能存在的屬性,但是在find函數中,我增加了在原型鏈中額外搜索屬性的功能。

我假設您僅使用基元和對象/數組文字。 在這種情況下,以下方法(使用下划線)似乎可以解決問題。

var testSubject = {
    mykey: 9,
    firstArray: [
        {something: 9, another: {x: 'hello', mykey: 'dude'}, mykey: 'whatever'},
        {something: 9, another: {x: 'hello', mykey: 'dude2'}, mykey: 'whatever2'},
        {
            someArray: [
                {seven: 7, mykey: 'another'},
                {hasNo: 'mykey', atAll: 'mykey'}
            ]
        }
    ],
    anObject: {beef: 'jerky', mykey: 19}
};

function getValuesForKey(subject, searchKey) {
    return _.reduce(subject, function(memo, value, key) {
        if (_.isObject(value)) {
            memo = memo.concat(getValuesForKey(value, searchKey));
        } else if (key === searchKey) {
            memo.push(value);
        }
        return memo;
    }, []);
}

console.log(getValuesForKey(testSubject, 'mykey'));
// -> [9, "dude", "whatever", "dude2", "whatever2", "another", 19] 

它僅返回值列表,因為它們將共享相同的鍵(即指定的鍵)。 另外,我確實相信,如果任何匹配的鍵的值不是原始的,它們都將被忽略(例如,應忽略mykey: {…}mykey: […] )。 希望對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM