从对象数组中获取键值数组,而不知道对象数组的格式(Javascript)?

从对象数组中获取键值数组,而不知道对象数组的格式(Javascript)?,javascript,jquery,arrays,underscore.js,Javascript,Jquery,Arrays,Underscore.js,假设我得到一个类似对象数组的引用,例如,array将是该数组的名称。现在我被要求创建一个数组,其中包含在该数组的每个对象中找到的某个属性的所有值,例如“user.id” 问题是我不知道每个对象的格式以及该属性将驻留/嵌套的位置。因此“user.id”可能驻留在数组[#]中。someKey(数组[#].someKey[“user.id”])或数组[#]中。someKey.someOtherKey(数组[#]someKey.someOtherKey[“user.id]”) 是否有一个函数(jQuer

假设我得到一个类似对象数组的引用,例如,
array
将是该数组的名称。现在我被要求创建一个数组,其中包含在该数组的每个对象中找到的某个属性的所有值,例如
“user.id”

问题是我不知道每个对象的格式以及该属性将驻留/嵌套的位置。因此
“user.id”
可能驻留在
数组[#]中。someKey
数组[#].someKey[“user.id”]
)或
数组[#]中。someKey.someOtherKey
数组[#]someKey.someOtherKey[“user.id]”

是否有一个函数(jQuery、下划线..等)可以创建这样的数组? e、 g.
var arrayOfUserIds=returnArray(数组,“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"]);
}
var arrayOfUserIds=[];

对于(var i=0;i如果我理解正确,
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
函数中,我添加了在原型链中额外搜索属性的功能。

如果我理解正确,someArray
中的每个对象要么包含一个属性
user.id
,要么包含一个的对象e> 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
函数中,我添加了在原型链中额外搜索属性的功能。

如果我理解正确,someArray中的每个对象要么包含一个属性
user.id
,要么包含一个的对象e> 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
函数中,我添加了在原型链中额外搜索属性的功能。

如果我理解正确,someArray中的每个对象要么包含一个属性
user.id
,要么包含一个的对象e> 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:[…]
应忽略),则会忽略任何匹配键。我希望这会有所帮助。

我假设您只处理原语和对象/数组文本。在这种情况下,下面的方法(使用下划线)似乎可以解决问题

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:[…]
应忽略),则会忽略任何匹配键。我希望这会有所帮助。

我假设您只处理原语和对象/数组文本。在这种情况下,下面的方法(使用下划线)似乎可以解决问题

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:[…]
应忽略),则会忽略任何匹配键.我希望这会有帮助。

我假设你只在工作