Is it possible to retrieve several columns using the pluck method in Underscore.js following the input from the where method, similar to LINQ

var persons = [
    {name : "Alice", location : "paris", amount : 5},
    {name : "Bob", location : "tokyo", amount : 3},
    {name : "Eve", location : "london", amount : 10}
];

var filteredResults=_.pluck(_.where(persons, {location : "paris"}), 'name');

For instance: I am looking for name and amount.

Answer №1

To project to multiple properties, utilize map instead of 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}]

(Fiddle)

If desired, a helper method called "pluckMany" can be created to achieve the same functionality as pluck with variable arguments:

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

The _.mixin function can be used to add a "pluckMany" function to the _ namespace. This allows for a simpler syntax like:

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

(Fiddle)

Answer №2

TL;DR Just use :

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

However, it's worth reading further for the explanations as the process of discovering this solution is more intriguing than the answer itself.


The basic structure would be (also applicable with lodash) :

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

Given this fundamental map function that transforms each element of a collection, there are various ways to customize it to your specific case (showcasing the versatility of map, essential in functional programming).

Below are several approaches to implement our solution :

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

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

...

console.log(results);

If you appreciate coding with underscore or lodash, exploring functional programming is highly recommended, since this style and many functions (map, reduce among others) originate from there.

Note: This seems to be a common query in the realm of underscore: https://github.com/jashkenas/underscore/issues/1104

It appears intentional that these functionalities are not included in underscore/lodash: "composability surpasses features". One could also say do one thing and do it well. Hence, the existence of _.mixin.

Answer №3

Ah, how I long for the day when pluck will accept an array as input. But for now, you can achieve a similar result with this workaround:

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

Answer №4

From what I've gathered, the individual who posed the question is interested in simplifying an array of objects by extracting only a few key properties from each object.

There are countless methods to achieve this outcome using various tools, but the one that resonates with me is as follows. Start by initializing an empty result object, which will serve as the context within the function. Then, utilize a combination of iteration using _.each and property selection with _.pick to extract the desired fields:

var myObjects = [
    { "first" : "Alice",
      "last" : "Smith",
      "age" : 30
    },
    { "first" : "Bob",
      "last" : "Johnson",
      "age" : 45
    }
];

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

console.log(result);

Answer №5

YAAUu-Yet Another Response Employing underscore...

// ensure to utilize a capable browser for executing this code snippet, ideally an es6-compliant browser
let individuals = [{
    firstName: "Alice",
    city: "la",
    qty: 7
  },
  {
    firstName: "Sam",
    city: "la",
    qty: 2
  },
  {
    firstName: "Mia",
    city: "sf",
    qty: 6
  }
];
// you have the option to select the properties you desire 
let selecting = _.iteratee((person) => _(person).pick("firstName", "city"));
// alternatively, you can exclude the properties you don't need
let excluding = _.iteratee((person) => _(person).omit("qty"));
// establish the filter based on city
let residing = (individuals, city) => _(individuals).where({
  "city": city
});
// incorporate the "filter by city" into a mixin (presuming it will be reused multiple times)
_.mixin({
  residing: residing
});
// perform the operation (twice), 
// these chain methods could also be integrated into a mixin
console.log("outcomes with selected properties:", _(individuals).chain().residing("la").map(selecting).value());
console.log("results with excluded properties:", _(individuals).chain().residing("la").map(excluding).value());
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

Answer №6

A more concise approach could be to use a single line of code:

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

Answer №7

Avoid using pluck, you can achieve the desired result with omit too.

const updatedList = _.map(users, function(user) {
  return _.omit(user, 'email');
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Getting rid of an Ajax loader graphic after a period of time

After a button is clicked, I have an ajax loader that appears and here is the code snippet: jQuery(document).ready(function($) { $('#form').on('submit', function() { $('#submit').css('display', 'bl ...

Is there a way to work around the CORS policy in order to fetch data from URLs?

I have been developing a tool that can analyze URLs from an uploaded CSV file, search the text content of each URL, and calculate the total word count as well as the occurrences of "saas" or "software". The goal is to generate a new CSV file with the origi ...

By default, the HTML table will highlight the specific column based on the current month using either AngularJS or JavaScript upon loading

I am working with a table of 10 products and their monthly sales data. Using Angular JS, I am looking to highlight the entire column based on the current month and year. Additionally, we will also be incorporating future expected sales data into the table. ...

Is it possible that adding html tables together could result in the numbers being concatenated instead of summed?

When attempting to calculate the total sum of values in an html table column, my variable seems to be returning concatenated strings instead of the actual sum. For example, instead of 1 + 2 + 3 = 6, I am getting 1 + 2 + 3 = 123. The values in the "votes" ...

Converting a TypeScript object into a JSON string

When working with TypeScript, I am facing a challenge while trying to initialize an object that requires a JSON string for the "options" parameter. Specifically, it pertains to the object mentioned here. It is crucial that the options parameter be in JSON ...

Toggling forms with HTML <select> elements: A step-by-step guide

In the process of creating a web application, I am faced with the task of registering users based on their specific category. To accomplish this, I have incorporated a combo-box where users can indicate their user type. My objective is to display an appro ...

Increasing the sms counter in javascript once it reaches 160 characters

I am facing an issue with my two counters that are used to track the number of characters in a message. Everything works fine until 160 characters, but after that point, the first counter stops at 0 instead of resetting back to 160 and decreasing from ther ...

What do you mean my cookie isn't working?

I'm going crazy over this! There's a cookie that was set from a response header with the sessionid, visible in dev tools on Chrome and Firefox, but document.cookie shows an empty string. This is what the cookie looks like: Name: sessionid Value ...

What is the best way to incorporate Drift bot JS code into a static React NextJs application, such as a landing page?

I'm a beginner with ReactJS and I recently created a static website using ReactJS & NextJs. I decided to integrate a chatbot called 'Drift', but when following the installation instructions to insert JavaScript code in the <head> of HT ...

Why won't the jQuery function trigger when I click, but only responds when I move the cursor?

I am currently working on a website that includes a basic CSS style switcher. The function responsible for handling the theme button clicks is shown below: <script> $(function() { $(".light").click(function(){ $("link").attr("href", ...

When I use my loop to generate Google Map markers, the positioning is not accurate and the markers do not appear on the map. However, manually inputting the positions

There seems to be an issue with displaying Google map markers based on objects in the markers array after looping through it. I noticed that when creating a second component and setting the position manually, the marker appears correctly. However, upon ins ...

The <br/> tag is not functioning properly when retrieving text from a MySQL query

Currently, I am involved in a project that involves an A.I pushing text onto a MySQL database. Our goal is to display the ongoing writing process on a webpage. We are still actively working on this. We are retrieving the data and regularly checking the da ...

Iteratively traverse the object to establish connections between parent and child elements

I've been working on creating a recursive function with some guidance I received here: looping through an object (tree) recursively The goal is to traverse the object 'o' and generate a new one where each key is associated with its parents ...

Viewer model aggregation - coordinating problem

In the Viewer, I am dynamically aggregating models from multiple BIM files. The process involves initializing the viewer and then using LoadDocument and LoadModel for each model chosen by the user. These models are primarily NVC files (the ones I used for ...

Different ways to categorize and tally a collection of objects

I'm having trouble reshaping my data in order to create a stacked bar graph. The data from the backend is structured like this: [ {date: 'January', category: 'A'}, {date: 'January', category: 'B'}, ...

An exploration on integrating a controller into an Angular directive class using Typescript

Here's the TypeScript code for an Angular directive class I've been working on: I'm wondering how I can incorporate a controller into this directive without creating a separate controller class. My goal is to write and inject the ISOLATE SC ...

Leveraging Vue.js to preload data with client-side rendering

When it comes to server-side rendering in Vue, like with Nuxt, the process involves grabbing data using the serverPrefetch() function and rendering content on the server side. This allows for the request to return data to the user only after the initial do ...

Having trouble getting the CSS class to work in MVC4 with jQuery implementation

I recently created a view page where I implemented some jQuery code: <script type="text/javascript"> $(document).ready(function () { var hdrname = $('#headername').text(); alert(hdrname); if (hdrname == "Pending Assignment") { ...

`Only firing event listener once`

I have created a JS module where I am adding a click event to all links that match a specific selector. Here is an example of how it's done: var Lightbox = (function () { var showLightbox = function () { // this does stuff }; var init = fu ...