0

Given an object searchable, is there a simple way of returning all the id values using lodash or underscore.js (or equivalent) where I can define the path to id?

const searchable = {
    things: [
        {
            id: 'thing-id-one',
            properties: [
                { id: 'd1-i1' },
                { id: 'd1-i2' },
            ]
        },
        {
            id: 'thing-id-two',
            properties: [
                { id: 'd2-i1' },
                { id: 'd2-i2' },
            ]
        }
    ]
}

I am looking to see if this is possible in a manner similar to how we can use lodash.get e.g. if we wanted to return the things array from searchable we could do

const things = _.get(searchable, 'things');

I can't seem to find anything similar in the documentation. I am looking for something that could contain an implementation similar to:

_.<some_function>(searchable, 'things[].properties[].id') 

Note: I am well aware of functions like Array.map etc and there are numerous ways of extracting the id property - it is this specific use case that I am trying to figure out, what library could support passing a path as a string like above or does lodash/underscore support such a method.

3 Answers 3

1

Found a solution using the package jsonpath

const jp = require('jsonpath');
      
const result = jp.query(searchable, '$.things[*].properties[*].id')
console.log(result);

// outputs: [ 'd1-i1', 'd1-i2', 'd2-i1', 'd2-i2' ]
Sign up to request clarification or add additional context in comments.

Comments

0

you can do it easily in plain js

like this

const searchable = {
    things: [
        {
            id: 'thing-id-one',
            properties: [
                { id: 'd1-i1' },
                { id: 'd1-i2' },
            ]
        },
        {
            id: 'thing-id-two',
            properties: [
                { id: 'd2-i1' },
                { id: 'd2-i2' },
            ]
        }
    ]
}

const search = (data, k) => {
  
  if(typeof data !== 'object'){
    return []
  }
  return Object.entries(data).flatMap(([key, value]) => key === k ? [value]: search(value, k))
}

console.log(search(searchable, 'id'))

1 Comment

I like the recursive algorithm, but I suspect the question is asking specifically how to target the ids of the properties.
0

_.map and _.flatten together with iteratee shorthands let you expand nested properties. Every time you need to expand into an array, just chain another map and flatten:

const searchable = {
    things: [
        {
            id: 'thing-id-one',
            properties: [
                { id: 'd1-i1' },
                { id: 'd1-i2' },
            ]
        },
        {
            id: 'thing-id-two',
            properties: [
                { id: 'd2-i1' },
                { id: 'd2-i2' },
            ]
        }
    ]
}

// Let's say the path is "things[].properties[].id"
const result = _.chain(searchable)
.get('things').map('properties').flatten()
.map('id').value();

console.log(result);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/underscore-umd-min.js"></script>

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.