4
\$\begingroup\$

This does what I want:

function test(data){
    for(var key in data){
        if(/_is$/.test(key)){
          var obj = {}
          obj[key] = data[key];
          return obj;
        }
    }
}

test( {a: 'a', user_id_is: '1', b: 'b'} )
> Object {user_id_is: "1"}

But 8 lines of code for such a simple task looks inefficient. Is there a more concise way to achieve such a basic task in JavaScript, something like how Ruby does it?

data.detect {|item| item =~ /_is$/}
\$\endgroup\$
2
  • \$\begingroup\$ Very nice question, welcome to Code Review! \$\endgroup\$
    – janos
    Commented Jun 3, 2016 at 6:20
  • 1
    \$\begingroup\$ What do you mean by "the first key/value pair"? I don't believe that object attributes are in any particular order. Do you mean "any matching key"? \$\endgroup\$ Commented Jun 3, 2016 at 6:22

1 Answer 1

2
\$\begingroup\$

To be fair, the entire thing in Ruby would be a few more method calls:

{:a => 1, :b => 2}.detect { |i| i != :b }.each_slice(2).to_h

Can we do this in a similar number of lines in JavaScript?

First, we can shorten the 8 line original down to 5 lines if we use ES2015 syntax:

function test(data) {
  for(let key of data) {
    if(/_is$/.test(key)) return {[key]: data[key]};
  }
}

Adding in ES2015 methods we can use reduce and an arrow function to get rid of the return at the cost of making this always loop over all the keys in the object (now down to 3 lines):

const test = data => Object.keys(data).reduce((obj, key) =>
  obj || /_is$/.test(key) ? {[key]: data[key]} : undefined, undefined
);

If we're willing to use ES2017, we can use Object.entries and a helper function to get the line count down to 2 at the expense of a little legibility:

const toObj = ([key, value] = []) => key ? {[key]: value} : undefined;
const test = data => toObj(Object.entries(data).find(([key, value]) => /_is$/.test(key)));
\$\endgroup\$
2
  • \$\begingroup\$ Very nice answer, welcome to Code Review! \$\endgroup\$
    – janos
    Commented Jun 3, 2016 at 6:20
  • \$\begingroup\$ Note: for..in and for..of do different things, so it depends on what OP is using for data. \$\endgroup\$
    – gcampbell
    Commented Jun 8, 2016 at 18:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.