14

In rails, i have a special slice method to keep in Hash only keys I need. It is very handy to permit only required keys in a hash.

Is there a method like this in Node.js?

starwars25
  • 395
  • 1
  • 5
  • 13
  • 1
    Possible duplicate of [How to get a subset of a javascript object's properties](https://stackoverflow.com/questions/17781472/how-to-get-a-subset-of-a-javascript-objects-properties) – kuboon Nov 08 '18 at 06:58

5 Answers5

21

In JavaScript there is no such method, however, in libraries like lodash there is the method called _.pick

var data = { a: 1, b: 2, c: 3 };
console.log(_.pick(data, 'a', 'c'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>

you can install lodash via npm

npm install lodash --save

and then require it to your project

var _ = require('lodash') // import all methods
// or just import pick method
// var pick = require('lodash/object/pick');

Or you can implement your own pick with new ES features, like so

const data = { a: 1, b: 2, c: 3 };

const pick = (obj, ...args) => ({
  ...args.reduce((res, key) => ({ ...res, [key]: obj[key] }), { })
})

console.log(
  pick(data, 'a', 'b')
)
Oleksandr T.
  • 76,493
  • 17
  • 173
  • 144
17

These are the coolest solutions.

Hard corded version: https://stackoverflow.com/a/39333479/683157

const object = { a: 5, b: 6, c: 7  };
const picked = (({ a, c }) => ({ a, c }))(object);

console.log(picked); // { a: 5, c: 7 }

Generic version: https://stackoverflow.com/a/32184094/683157

const pick = (...props) => o => props.reduce((a, e) => ({ ...a, [e]: o[e] }), {});
pick('color', 'height')(elmo);
kuboon
  • 9,557
  • 3
  • 42
  • 32
5

Similar to what @Brandon Belvin said, here is an ES6 equivalent:

/**
 * A pure function to pick specific keys from object, similar to https://lodash.com/docs/4.17.4#pick
 * @param {Object}obj: The object to pick the specified keys from
 * @param {Array}keys: A list of all keys to pick from obj
 */
const pick = (obj, keys) => 
  Object.keys(obj)
    .filter(i => keys.includes(i))
    .reduce((acc, key) => {
      acc[key] = obj[key];
      return acc;
    }, {})

// Test code
const data = { a: 1, b: 2, c: 3 };
console.log(pick(data, ['a', 'c']));

Here is the gist I have created for common functional utilities, including the definition of pick(), similar to https://lodash.com/docs/4.17.4#pick

Aditya Singh
  • 15,810
  • 15
  • 45
  • 67
2

You can accomplish this with what's already built into JavaScript. Here's a quick method that's compatible with ES5 (and can be made slightly more concise in ES2015):

function slice(object, keys) {
    return Object.keys(object)
        .filter(function (key) {
            return keys.indexOf(key) >= 0;
        })
        .reduce(function (acc, key) {
            acc[key] = object[key];
            return acc;
        }, {});
}

This method purposefully does not mutate the object it's inspecting. So if you want to change the original object, just assign the output of slice to your original variable.

var x = { a: 1, b: 2, c: 3, d: 4 };
var y = slice(x, [ 'b', 'd' ]);

console.log(x);
// { a: 1, b: 2, c: 3, d: 4 }

console.log(y);
// { b: 2, d: 4 }

This will work for simple applications where you only need to look at the first-level keys, but you can expand this to behave recursively, if necessary.

Brandon Belvin
  • 445
  • 7
  • 14
1

Seems to me that you have three options available.

  1. delete the properties you do not need, or
  2. copy/clone the object and then delete the properties you don't need.
  3. apply some filtering conditions while copying/cloning the object.

Without more info it's difficult to know the best approach to copying/cloning an object, but as you mentioned hash tables one might presume that you are talking about Object literals. The follow code works, but whether it is the 'best' approach is perhaps something others will be willing to comment on (also see this StackOverflow question).

var hashTable = {
    d1: '1',
    d2: '2',
    d3: '3',
    d4: '4',
    d5: '5',
    d6: '6'
};
var filter = new RegExp("d1|d3|d5");

function cloneHashTable(table, conditions) {
    var obj = {};

    for (var h in table) {
        if (table.hasOwnProperty(h)) {
            if (h.match(conditions) !== null) obj[h] = table[h];
        }
    }
    return obj;
}

var hashClone = cloneHashTable(hashTable, filter);

console.debug(hashTable);
console.debug(hashClone);

//=> Object { d1: "1", d2: "2", d3: "3", d4: "4", d5: "5", d6: "6" }
//=> Object { d1: "1", d3: "3", d5: "5" }

Of course, this only works if you know what is in the table and you know what you want/need from it - and what you don't.

Hope this helped. :)

Community
  • 1
  • 1
Brian Peacock
  • 1,801
  • 16
  • 24