Подтвердить что ты не робот

В подчёркнутом js, могу ли я получить несколько столбцов с помощью метода pluck после ввода, где метод, когда linq выбирает проекцию

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

Например: мне нужны firstName и qty.

4b9b3361

Ответ 1

Чтобы проецировать несколько свойств, вам нужно map, а не отрывать:

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

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

(Fiddle)

Обратите внимание, что если бы вы захотели, вы могли бы создать вспомогательный метод "pluckMany", который делает то же самое, что и с переменными аргументами:

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

Вы можете использовать функцию _.mixin, чтобы добавить функцию "pluckMany" в пространство имен _. Используя это, вы можете просто написать:

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

(Fiddle)

Ответ 2

TL; DR Использование:

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

Но, пожалуйста, прочитайте для объяснений, поскольку я считаю, что процесс поиска этого решения более интересен, чем фактический ответ.


Общий шаблон будет (он работает с lodash):

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

Учитывая эту общую функцию map, которая преобразует каждый элемент коллекции, существует несколько способов адаптировать это к вашей конкретной ситуации (что vouch для гибкости map, который является очень базовым строительным блоком функциональных программ).

Предлагаю несколько вариантов реализации нашего решения:

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

Если вам нравится этот способ написания кода с underscore или lodash, я настоятельно рекомендую вам взглянуть на функциональное программирование, так как этот стиль письма, а также множество функций (map, reduce среди многих других) оттуда.

Примечание: Это, по-видимому, общий вопрос в подчеркивании: https://github.com/jashkenas/underscore/issues/1104

Это, по всей видимости, не случайно, если они не учтены под подчеркиванием /lodash: "композиция лучше, чем функции". Вы также можете сказать do one thing and do it well. Именно поэтому существует _.mixin.

Ответ 3

Мое понимание - это автор вопроса, который хочет взять массив объектов со многими свойствами и разбивать каждый объект на небольшой список свойств.

Есть множество способов сделать это с помощью _, но мне это нравится лучше всего. Передайте пустой объект результата, который будет "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);

Ответ 4

Да, я бы хотел, чтобы pluck имел возможность передать массив, но тем временем вы могли бы сделать:

function pluckFields(arr, fields) {
  return _.map(arr, function(item) {
    return _.pick(item, fields)
  })
}

Ответ 5

Эта линейная может сохранить несколько строк:

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

Ответ 6

YAAUu -Yep Другой ответ Использование подчеркивания...

// 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>

Ответ 7

Нам не нужно использовать щипку, опустить и трюк.

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