javascript 在下划线 js 中,我可以在输入 where 方法作为 linq select 投影后使用 pluck 方法获得多列吗

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19349881/
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-27 15:17:15  来源:igfitidea点击:

At underscore js, Can I get multiple columns with pluck method after input where method as linq select projection

javascriptunderscore.js

提问by ttacompu

var people = [
    {firstName : "Thein", city : "ny", qty : 5},
    {firstName : "Michael", city : "ny", qty : 3},
    {firstName : "Bloom", city : "nj", qty : 10}
];

var results=_.pluck(_.where(people, {city : "ny"}), 'firstName');

For example : I need firstNameand qty.

例如:我需要firstNameqty

回答by McGarnagle

To project to multiple properties, you need map, not pluck:

要投影到多个属性,您需要map,而不是 pluck:

var results = _.map(
    _.where(people, {city : "ny"}), 
    function(person) {
        return { firstName: person.firstName, qty: person.qty };
    }
);

[{"firstName":"Thein","qty":5},{"firstName":"Michael","qty":3}]

[{"firstName":"Thein","qty":5},{"firstName":"Michael","qty":3}]

(Fiddle)

(小提琴)

Note that, if you wanted to, you could create a helper method "pluckMany" that does the same thing as pluck with variable arguments:

请注意,如果您愿意,可以创建一个辅助方法“pluckMany”,它与带有可变参数的 pluck 执行相同的操作:

// first argument is the source array, followed by one or more property names
var pluckMany = function() {
    // get the property names to pluck
    var source = arguments[0];
    var propertiesToPluck = _.rest(arguments, 1);
    return _.map(source, function(item) {
        var obj = {};
        _.each(propertiesToPluck, function(property) {
            obj[property] = item[property]; 
        });
        return obj;
    });
};

You can use the _.mixinfunction to add a "pluckMany" function to the _namespace. Using this you can write simply:

您可以使用该_.mixin函数向_命名空间添加“pluckMany”函数。使用它,您可以简单地编写:

var results = _.chain(people).where({city : "ny"}).pluckMany( "firstName", "qty").value();

(Fiddle)

(小提琴)

回答by nha

TL;DRUse :

TL;DR使用:

var results = _.chain(people)
    .where({ city: "ny" })
    .map(_.partialRight(_.pick, 'firstName', 'qty'))
    .value();

But please read on for explanations as I feel the process of finding this solution is more interesting than the actual answer.

但是请继续阅读以获取解释,因为我觉得找到此解决方案的过程比实际答案更有趣。



The general pattern would be (it works with lodashtoo) :

一般模式是(它也适用lodash):

_.map(array, function(obj) { return _.pick(obj, 'x', 'y', 'z'); });

_.map(array, function(obj) { return _.pick(obj, 'x', 'y', 'z'); });

Given this general mapfunction which transforms each element of a collection, there are multiple ways to adapt this to your particular situation (that vouch for the flexibility of map, which is a very basic building block of functional programs).

鉴于这种map转换集合中每个元素的通用函数,有多种方法可以使其适应您的特定情况(这保证了 的灵活性map,这是函数式程序的一个非常基本的构建块)。

Let me present below several ways to implement our solution :

让我在下面介绍几种实现我们解决方案的方法:

var _ = require('lodash'); // @lodash 2.4.1 at the time of writing
// use underscore if you want to, but please see http://stackoverflow.com/questions/13789618/differences-between-lodash-and-underscore


/* la data */
var people = [{
    firstName: "Thein",
    city: "ny",
    qty: 5
}, {
    firstName: "Michael",
    city: "ny",
    qty: 3
}, {
    firstName: "Bloom",
    city: "nj",
    qty: 10
}];


/* OPTION1 : mixin' with _ */
_.mixin({
    pluckMany: function() {
        var array = arguments[0],
            propertiesToPluck = _.rest(arguments, 1);

        return _.map(array, function(item) {

            /* Alternative implementation 1.1
             * ------------------------------
             * Taken from @mMcGarnagle answer
             * _each is easy to understand here,
             * but has to modify the variable `obj` from a closure
             * I try to avoid that for trivial cases like this one.
             */
            var obj = {};
            _.each(propertiesToPluck, function(property) {
                obj[property] = item[property];
            });
            return obj;


            /* Alternative implementation 1.2
             * ------------------------------
             * Rewrite the previous code,
             * by passing the accumulator (previously`obj`, but really it is an object that accumulates the result being constructed) across function calls.
             * This construction is typical of the `reduce` function, closer to a functionnal programming style.
             */
            return _.reduce(propertiesToPluck, function(obj, property) {
                obj[property] = item[property];
                return obj;
            }, {});


            /* Alternative implementation 1.3
             * ------------------------------
             * If we are already using lodash/underscore,
             * then let's use the `pick` function ! I also included an example of `flatten` here
             */
            return _.pick(item, _.flatten(propertiesToPluck, true));


            /* Alternative implementation 1.4
             * ------------------------------
             * But really flatten is not needed.
             */
            return _.partial(_.pick, item).apply(null, propertiesToPluck);
        });
    }
});



/* Let's use our mixed function !
 * Since we call several _ functions on the same object
 * it is more readable to chain the calls.
 */
var results = _.chain(people)
    .where({
        city: "ny"
    })
    .pluckMany('firstName', 'qty')
    .value();



/* OPTION 2 : without mixing our code with lodash/underscore */
var results = _.chain(people)
    .where({
        city: "ny"
    })
    .map(_.partialRight(_.pick, 'firstName', 'qty'))
    .value();

console.log(results);

If you like this way of writing code with underscoreor lodash, I highly suggest that you have a look at functional programming, as this style of writing as well as many functions (map, reduceamongst many others) come from there.

如果您喜欢使用underscore或编写代码的这种方式lodash,我强烈建议您查看函数式编程,因为这种编写方式以及许多函数(mapreduce以及许多其他函数)都来自于那里。

Note :This is apparently a common question in underscore : https://github.com/jashkenas/underscore/issues/1104

注意:这显然是下划线中的常见问题:https: //github.com/jashkenas/underscore/issues/1104

This is apparently no accident if these are left out of underscore/lodash : "composability is better than features". You could also say do one thing and do it well. This is also why _.mixinexists.

如果将它们排除在下划线/lodash 之外,这显然不是偶然的:“可组合性优于功能”。你也可以说do one thing and do it well。这也是_.mixin存在的原因。

回答by tldr

Yep, I wish pluckhad an option of passing an array, but in the meantime, you could do:

是的,我希望pluck有一个传递数组的选项,但与此同时,你可以这样做:

const pluckFields = (arr, fields) => _.map(arr, item => _.pick(item, fields))

回答by eeejay

My understanding is the author of the question wants to take an array of objects with many properties and strip each object down to a small list of properties.

我的理解是问题的作者想要获取具有许多属性的对象数组并将每个对象分解为一个小的属性列表。

There are myriad ways of doing so with _ , but I like this way best. Pass in an empty result object which will be "this" inside the function. Iterate with _each , and _pick the fields you want:

_ 有无数种方法可以这样做,但我最喜欢这种方式。传入一个空的结果对象,该对象将是函数内部的“this”。使用 _each 进行迭代,然后 _pick 所需的字段:

var myObjects = [
    { "first" : "eric",
      "last" : "gumbo",
      "code" : "x482"
    },
    { "first" : "john",
      "last" : "dinkman",
      "code" : "y9283"
    }
];

var result = [];
_.each( myObjects, function(itm) { this.push(_.pick(itm,"first","code")) }, result );

console.log(result);

回答by zobidafly

YAAUu-Yep Another Answer Using underscore...

YAAUu - 是的,使用下划线的另一个答案...

// use a proper browser to run this code snippet, a browser that is es6-compliant
let people = [{
    firstName: "Thein",
    city: "ny",
    qty: 5
  },
  {
    firstName: "Michael",
    city: "ny",
    qty: 3
  },
  {
    firstName: "Bloom",
    city: "nj",
    qty: 10
  }
];
// either you pick the properties you want 
let picking = _.iteratee((person) => _(person).pick("firstName", "city"));
// either you omit the properties you do not want
let omitting = _.iteratee((person) => _(person).omit("qty"));
// create the filter by city
let living = (people, city) => _(people).where({
  "city": city
});
// put the "filter by city" into a mixin (as I assume it would be used again & again)
_.mixin({
  living: living
});
// do the thing (twice), 
// these chaining methods could be done into a mixin as well
console.log("results by picking properties:", _(people).chain().living("ny").map(picking).value());
console.log("results by omitting properties:", _(people).chain().living("ny").map(omitting).value());
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

回答by Nadeem

That one linear might save some lines:

那个线性可能会节省一些行:

var results=_.pick(_.where(people, {city : "ny"}), 'firstName', 'qty');

回答by Arthuang

We don't have to use pluck, omit do the trick as well.

我们不必使用 pluck,也可以省略 do 这个技巧。

var result = _.map(people, function(person) {
  return _.omit(person, 'city');
});