neo33
neo33

Reputation: 1879

How to filter a dictionary by value in JavaScript?

I am writing a script to create a dictionary called dict, where I store the the frequencies of some words that I have in a text area. My array looks like this:

var dict = removeArray.reduce(function(p,c) {
    if (p[c] === undefined) {
        p[c] = 1;
    } else {
        p[c]++;
    }
    return p;
}, {});

I would like to filter the elements of this dictionary by their value. I need to create a list with the words that have a value greater than one. My dictionary looks like this:

{
    "92173": 6,
    "C": 6,
    "GJHGWO.NAYE": 1,
    "GJHGX4.NAYE": 1,
    "GJHGX6.NAYE": 1,
    "GJHGX8.NAYE": 1,
    "GJHGXA.NAYE": 1,
    "GJHGXC.NAYE": 1,
    "RBD": 10,
    "RBD3": 2,
    "SAMBORNSiPOSSSTHRa": 2,
    "SAMBORNSiPOSSSTHRa1": 2,
    "SAMBORNSiPOSSSTHRa2": 2,
    "X": 4,
    "X3": 2
}

In order to achieve that I tried using lodash, as follows:

var filtered = _.find(dict, function(user) {
    return user.frecuency > 1;
});

But I failed since I got:

undefined

I don't know how to use lodash appropriately to filter this array.

My complete code looks like this:

var splitWords = document.getElementById("texto").value.split(/[["\|~]/);
var removeArray  = _.remove(splitWords, function (word) {
    return word !== '' && word !== ' ' && word !== '\n'
});

var dict = removeArray.reduce(function(p,c) {
    if (p[c] === undefined) {
        p[c] = 1;
    } else {
        p[c]++;
    }
    return p;
}, {});
console.log(dict);

var filtered = _.find(dict, function(user) {
  return user.frecuency > 1;
});

console.log(filtered)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<p id="demo"></p>
<textarea cols="150" rows="15" id="texto">
"RBD|X|RBD3|C|92173~GJHGWO.NAYE"
"SAMBORNSiPOSSSTHRa1"
"RBD|X|RBD|C|92173~GJHGX4.NAYE"
"SAMBORNSiPOSSSTHRa"
"RBD|X3|RBD3|C|92173~GJHGX6.NAYE"
"SAMBORNSiPOSSSTHRa1"
"RBD|X|RBD|C|92173~GJHGX8.NAYE"
"SAMBORNSiPOSSSTHRa2"
"RBD|X|RBD|C|92173~GJHGXA.NAYE"
"SAMBORNSiPOSSSTHRa2"
"RBD|X3|RBD|C|92173~GJHGXC.NAYE"
"SAMBORNSiPOSSSTHRa"
</textarea>

Upvotes: 37

Views: 76081

Answers (1)

trincot
trincot

Reputation: 350725

You could use reduce again to achieve that in plain JavaScript:

var filtered = Object.keys(dict).reduce(function (filtered, key) {
    if (dict[key] > 1) filtered[key] = dict[key];
    return filtered;
}, {});

With some ES6 features, such as arrow functions, spread syntax, Object.entries, ... it can look like this:

var filtered = Object.assign({}, ...
    Object.entries(dict).filter(([k,v]) => v>1).map(([k,v]) => ({[k]:v}))
);

Or using the newer Object.fromEntries:

var filtered = Object.fromEntries(Object.entries(dict).filter(([k,v]) => v>1));

Using Lodash

There were a few issues with your attempt with lodash:

  • _.find is not intended for returning an object that takes a selection of key/values from a given object. You would need _.pickBy for that.
  • Your object values do not have a frecuency property; they are primitive values, so you should just have to return user > 1

Lodash code:

var filtered = _.pickBy(dict, function(user) {
  return user > 1;
});

Upvotes: 77

Related Questions