javascript _.pick 方法来匹配对象数组中的子属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15222493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 23:56:03  来源:igfitidea点击:

_.pick method to match the sub property in an objects array

javascriptunderscore.js

提问by bhargav

I am using _.pick method in the following manner

我以下列方式使用 _.pick 方法

suppose I have an array of strings which are nothing but property names I want to get from each object in array of objects

假设我有一个字符串数组,它们只是我想从对象数组中的每个对象获取的属性名称

var wantedPropArray=["prop1","prop2","prop3.name"];

Below is my objects array

下面是我的对象数组

var objectArray = [
        {"prop1":"prop1Data1","prop2":"prop2Data1","prop3":{"name":"Tom","age":"24","class":"graduate"},"prop4":"prop4Data1","prop5":"prop5Data1"},
        {"prop1":"prop1Data2","prop2":"prop2Data2","prop3":{"name":"Cat","age":"24","class":"graduate"},"prop4":"prop4Data2","prop5":"prop5Data2"}
        {"prop1":"prop1Data3","prop2":"prop2Data3","prop3":{"name":"Tom","age":"24","class":"graduate"},"prop4":"prop4Data3","prop5":"prop5Data3"}
        {"prop1":"prop1Data4","prop2":"prop2Data4","prop3":{"name":"Tom","age":"24","class":"graduate"},"prop4":"prop4Data4","prop5":"prop5Data4"}
    ]
for( var item in objectArray ){          
    var objectArrayOnlySelectedProperties = _.pick(objectArray[item] , wantedPropArray);
}

suppose for first iteration lets see objectArrayOnlySelectedProperties data, I am getting

假设第一次迭代让我们看到 objectArrayOnlySelectedProperties 数据,我得到

objectArrayOnlySelectedProperties = {"prop1":"prop1Data1","prop2":"prop2Data1"};

I am expecting it to give me the result something like this

我期待它给我这样的结果

objectArrayOnlySelectedProperties = {"prop1":"prop1Data1","prop2":"prop2Data1","prop3.name":"Tom"};

what i mean to say is _.pick method is not able to look into prop3 and get me prop3.name. Can anyone suggest how to use underscores' pick method to match the sub properties of each object in an array.

我的意思是 _.pick 方法无法查看 prop3 并获取我的 prop3.name。任何人都可以建议如何使用下划线的选择方法来匹配数组中每个对象的子属性。

Thanks in advance

提前致谢

采纳答案by Mike Hogan

It looks like this is not supported with underscorejs out of the box. But there is this gist that offers the support as a mix-in:

开箱即用的 underscorejs 似乎不支持此功能。但是有一个要点可以作为混合提供支持:

https://gist.github.com/furf/3208381

https://gist.github.com/furf/3208381

Here is some code using the above gist to do what you need: http://jsfiddle.net/wHXCv/1/

以下是一些使用上述要点来完成您需要的代码:http: //jsfiddle.net/wHXCv/1/

_.mixin({
  deep: function (obj, key) {
    var keys = key.split('.'),
        i = 0,
        value = null,
        n = keys.length;

      while ((obj = obj[keys[i++]]) != null && i < n) {};
      value = i < n ? void 0 : obj;
      var result = {};
      result[key]=value;
      return result;
  }
});

var objectArray = [
                 {"prop1":"prop1Data1","prop2":"prop2Data1","prop3":{"name":"Tom","age":"24","class":"graduate"},"prop4":"prop4Data1","prop5":"prop5Data1"},
                 {"prop1":"prop1Data2","prop2":"prop2Data2","prop3":{"name":"Cat","age":"24","class":"graduate"},"prop4":"prop4Data2","prop5":"prop5Data2"},
                 {"prop1":"prop1Data3","prop2":"prop2Data3","prop3":{"name":"Tom","age":"24","class":"graduate"},"prop4":"prop4Data3","prop5":"prop5Data3"},
                 {"prop1":"prop1Data4","prop2":"prop2Data4","prop3":{"name":"Tom","age":"24","class":"graduate"},"prop4":"prop4Data4","prop5":"prop5Data4"}];

var plucked = function(o, wantedPropArray) {
    return _.reduce(wantedPropArray, function(acc, val){
        acc.push(_.deep(o,val));
        return acc;
    },[]);
}

var answer = _.map(objectArray, function(o){
    return plucked(o, ["prop1","prop2","prop3.name"]);
});

console.log(JSON.stringify(answer));

回答by haitaka

I don't know about Underscore.js, but you may try this code:

我不知道 Underscore.js,但你可以试试这个代码:

function pick(obj,list){
    var newObj={};
    for(var i=0;i<list.length;i++){
        var str=list[i].split('.');
        var o=obj[str[0]];
        for(var j=1;j<str.length;j++){
            o=o[str[j]];
        }
        newObj[list[i]]=o;
    }
    return newObj;
}

回答by Mohsen

Underscore Deep Pick Plugin

下划线深度选择插件

I've created this plugin for underscore.js to help with problems like this.

我为 underscore.js 创建了这个插件来帮助解决这样的问题。

Deep Pick Pluging

深选择堵塞

Available at NPM and Bower

在 NPM 和 Bower 上可用

npm install deep_pick
bower install deep_pick

Example:

例子:

var input = {
  one: 1,
  two: true,
  three: 'Three',
  four: [1,2,3,4],
  five: {
    alpha: 1,
    beta: 2,
    gamma: 3,
    teta: {
        alef: 1,
        beh: 2,
        peh: 3
    }
  },
  answer: '42.00',
  description: 'This is an object.'
};


var schema = {
  one: true,
  three: true,
  five: {
    alpha: true,
    teta: {
      beh: true
    }
  }
};

deepPick(input, schema); // =>

{
  one: 1,
  three: "Three",
  five: {
    alpha: 1,
    teta: { 
      beh: 2
    }
  }
}

回答by styks

In case someone finds there way here. The _.pluckfunction is what you want. Comes with underscore.

万一有人在这里找到了方法。该_.pluck功能是你想要的。带有下划线。

http://underscorejs.org/#pluck

http://underscorejs.org/#pluck

回答by nof

lodash has some great methods for checking for and setting deep object properties: has, set, & get. You can use these functions to build up your own deepPick / deepPluck function. Below is an ES6 style function that builds on lodash and uses the built in Array.reduce method. Just a note that lodash uses the dot delimiter for nested properties.

lodash 有一些很好的方法来检查和设置深层对象属性:has、set 和 get。您可以使用这些函数来构建您自己的 deepPick / deepPluck 函数。下面是一个 ES6 风格的函数,它构建在 lodash 上并使用内置的 Array.reduce 方法。请注意,lodash 对嵌套属性使用点分隔符。

/**
 * Deep pick / pluck properties.
 *
 * @param {object} the source object
 * @param {array[string]} the properties to pick
 */
function deepPick (source, props) {
  return props.reduce((result, key) => {
    const exists = lodash.has(source, key);

    if (exists) {
      lodash.set(result, key, lodash.get(source, key));
    }

    return result;
  }, {});
}

回答by svestka

I've created a simple gist exactly for this: https://gist.github.com/peterslivka/9055188

我为此创建了一个简单的要点:https: //gist.github.com/peterslivka/9055188

_.mixin({ 
    pickDeep: function(obj) {
        var copy = {},
            keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));

        this.each(keys, function(key) {
            var subKeys = key.split('.');
            key = subKeys.shift();

            if (key in obj) {
                // pick nested properties
                if(subKeys.length>0) {
                    // extend property (if defined before)
                    if(copy[key]) {
                        _.extend(copy[key], _.pickDeep(obj[key], subKeys.join('.')));
                    }
                    else {
                        copy[key] = _.pickDeep(obj[key], subKeys.join('.'));
                    }
                }
                else {
                    copy[key] = obj[key];
                }
            }
        });

        return copy;
    }
});

You can find working example here: http://jsfiddle.net/TFfHk/

你可以在这里找到工作示例:http: //jsfiddle.net/TFfHk/