Colin Sygiel
Colin Sygiel

Reputation: 947

Javascript: How can I conditionally use Object.keys() to push specific keys into an array?

I have an object, let's say:

var stateValues = {
  CA: 423,
  MI: 90,
  IL: 200,
  OH: 56,
}

I want to put only the abbreviated states into an array if their values are below 100. I am using forEach() combined with Object.keys to try to do this. Can you please have a look at my code and tell me what I am doing wrong? Please advise me with ways to do with functional programming only because I must use functional programming for this problem.

Here's my attempt:

var stateValues = {
  CA: 423,
  MI: 90,
  IL: 200,
  OH: 56,
}

function lowState(state) {
  if (stateValues[state] < 100000) {
    return Object.keys(stateValues);
  }
}
var lowerSumStates = stateValues.forEach(lowState);

Upvotes: 2

Views: 1065

Answers (4)

vol7ron
vol7ron

Reputation: 42109

"use strict";

var stateValues = {
  CA: 423,
  MI: 90,
  IL: 200,
  OH: 56
};

function lowState(arr) {
  var [state,val]=arr;
  if (val < 100)
    return state;
}

var lowerSumStates = Object.entries(stateValues).map( lowState ).filter(v=>v);

console.log(lowerSumStates);

Here's the gist:

  • Object.entries takes the object and builds a two-dimensional array of key/val pairs
  • map() iterates over the array and calls your function
  • because entries is multidimentional, the argument to your function is an array of key and value, thus you can restructure it using the ES6 restructuring assignment (e.g., var [foo,bar]=[1,2]) *this isn't necessary, you could have worked with arr[1] and arr[0], but this is more maintainable
  • if the value is less than 100, it returns the state abbreviation, otherwise it will return undefined (because that's what map does), leaving you with an array like [undefined,'MI',undefined,'OH']
  • then you can easily remove the undefined by filtering on truthy values

Upvotes: 1

Nishanth Matha
Nishanth Matha

Reputation: 6081

The problem is foreach can only be used with arrays. And you're trying foreach with object which is undefined for sure. So try using for instead:

var stateValues = {
  CA: 423,
  MI: 90,
  IL: 200,
  OH: 56,
}

function lowState(stateValues) {
    var resultArray=[];
    for (var state in stateValues) {
      if (stateValues.hasOwnProperty(state) && stateValues[state] < 100) {
          resultArray.push(state);
      }
    }
    return resultArray;
}
var lowerSumStates = lowState(stateValues);
console.log(lowerSumStates);

Upvotes: 0

jas7457
jas7457

Reputation: 1782

If you combine keys, filter, and map, you can get your result that you're looking for.

var stateValues = { CA: 423, MI: 90, IL: 200, OH: 56 };
var lowerSumStates = Object.keys( stateValues )
      .filter( key => stateValues[key] < 100 )
      .map( key => stateValues[key] );

https://jsfiddle.net/gtfaqdbt/

Upvotes: 1

Andy Gaskell
Andy Gaskell

Reputation: 31761

Object.keys(stateValues)
      .filter(key => stateValues[key] > 100)
      .map(key => stateValues[key])

Upvotes: 0

Related Questions