4

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

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

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

下面是我的对象数组

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);
}

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

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

我期待它能给我这样的结果

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

我的意思是 _.pick 方法无法查看 prop3 并得到我的 prop3.name。谁能建议如何使用下划线的pick方法来匹配数组中每个对象的子属性。

提前致谢

4

6 回答 6

3

开箱即用的下划线js似乎不支持这一点。但是有一个要点可以作为混合提供支持:

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

这是一些使用上述要点的代码来做你需要的事情: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));
于 2013-03-05T11:28:27.987 回答
2

我不知道 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;
}
于 2013-03-05T11:36:12.567 回答
1

下划线深度选择插件

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

深镐堵塞

可在 NPM 和 Bower 购买

npm install deep_pick
bower install deep_pick

例子:

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
    }
  }
}
于 2014-05-23T22:59:36.067 回答
0

我为此创建了一个简单的要点: 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;
    }
});

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

于 2014-02-17T17:52:27.607 回答
0

以防有人在这里找到路。_.pluck功能就是你想要的。带有下划线。

http://underscorejs.org/#pluck

于 2016-01-11T20:07:06.587 回答
0

lodash 有一些很好的方法来检查和设置深层对象属性:has、set 和 get。您可以使用这些函数来构建您自己的 deepPick / deepPluck 函数。下面是一个基于 lodash 并使用内置 Array.reduce 方法的 ES6 风格函数。请注意,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;
  }, {});
}
于 2016-06-24T21:59:40.370 回答