Home > Software engineering >  Return all values of nested arrays using string identifier
Return all values of nested arrays using string identifier

Time:08-30

Give 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.

CodePudding user response:

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'))

CodePudding user response:

_.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>

CodePudding user response:

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' ]
  • Related