igo
igo

Reputation: 6848

Ramda: find object key by nested key value

Is there any function in ramda how can I find key by nested key value? I found a way how to find an object in array but that doesn't help. I need something like this:

const obj = {
  addCompany: {
    mutationId: '1'
  },
  addUser: {
    mutationId: '2'
  },
  addCompany: {
    mutationId: '3'
  }
}
const findByMutationId = R.???
findByMutationId('2', obj) // returns addUser

Upvotes: 1

Views: 16531

Answers (4)

Andreas Herd
Andreas Herd

Reputation: 1188

A bit late to the party but better late than never. You could also wrap some of the functions in curry() if you want to make them more composable in the future.

const obj = {
  addCompany: {
    mutationId: '1'
  },
  addUser: {
    mutationId: '2'
  },
  addCompany: {
    mutationId: '3'
  }
}

// search key in obj, where a value satisfies pred
const findObjKey = pred =>
  pipe(
    toPairs,
    find(compose(pred, nth(1))),
    nth(0)
  )

const findByMutationId = (id, obj) => findObjKey(propEq('mutationId', id))(obj)

const res = findByMutationId('2', obj)
console.log(res)

Upvotes: 0

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

find combined with propEq and keys should work

const obj = {
  addCompany: {
    mutationId: '1'
  },
  addUser: {
    mutationId: '2'
  },
  addCompany2: {
    mutationId: '3'
  }
}
const findByMutationId = id => obj => R.find(
  R.o(R.propEq('mutationId', id), R.flip(R.prop)(obj)),
  R.keys(obj)
)

console.log(findByMutationId('2')(obj))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>

Pointfree versions for the lulz

const obj = {
  addUser: {
    mutationId: '2'
  },
  addCompany: {
    mutationId: '3'
  }
}

const findByMutationId = R.compose(
  R.o(R.head),
  R.o(R.__, R.toPairs),
  R.find,
  R.o(R.__, R.nth(1)),
  R.propEq('mutationId')
)

console.log(findByMutationId('2')(obj))

const findByMutationId2 = R.compose(
  R.ap(R.__, R.keys),
  R.o(R.find),
  R.o(R.__, R.flip(R.prop)),
  R.o,
  R.propEq('mutationId')
)

console.log(findByMutationId2('3')(obj))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>

Upvotes: 4

Endless
Endless

Reputation: 37815

If you are gona use this then you might have to polyfill entries, this is good if you need both the key and the value

const obj = {
  addCompany: {
    mutationId: '1'
  },
  addUser: {
    mutationId: '2'
  },
  addCompany: {
    mutationId: '3'
  }
}

let [key, val] = Object.entries(obj).find(obj => obj[1].mutationId == '2')

console.log(key)
console.log(val)

Upvotes: 0

baao
baao

Reputation: 73241

Not sure about ramda, but if a one-liner in plain js is good for you, the following will work

const obj = {
    addCompany: {
        mutationId: '1'
    },
    addUser: {
        mutationId: '2'
    }
};

let found = Object.keys(obj).find(e => obj[e].mutationId === '2');
console.log(found);

Upvotes: 4

Related Questions