2

i have this data sample,

{
    "section": [
        {
            "id": 1,
            "name" : "dogs"
        },
        {
            "id": 2,
            "name" : "cats"
        }
    ],
    "price" : [
        {

            "name" : "monthly",
            "price": {
                "amount": 10
            }
        }
    ],
    "specs": {
        "color" : {
            "name" : "green"
        }
    }
}

i want to pick some properties from that object, like that

const obj = pick(obj,["section.id","price.price"])

it should gives an object:

{
    "section": [
        {
            "id": 1,
        },
        {
            "id": 2,
        }
    ],
    "price" : [
        {
            "price": {
                "amount": 10
            }
        }
    ],
}

i tried lodash.pick() and didn't understand the array of object case, it understand it if i used this syntax "section[0].name" and i want it generic, like "section.name"

2 Answers 2

2

You could take a custom pick function which take the wanted properties and takes all nested arrays without being part of the pathes.

function pick(object, keys) {
    if (Array.isArray(object)) return object.map(o => pick(o, keys));
    var pathes = keys.reduce((r, key) => {
        var [k, ...rest] = key.split('.'),
            temp = r.find(([l]) => k === l),
            left = rest.join('.');

        if (!(k in object)) return r;
        if (!temp) r.push(temp = [k, []]);
        if (left) temp[1].push(left);
        return r;
    }, []);
    return Object.assign({}, ...pathes.map(([k, rest]) => ({ [k]: rest.length
        ? pick(object[k], rest)
        : object[k]
    })));
}

var data = { section: [{ id: 1, name: "dogs" }, { id: 2, name: "cats" }], price: [{ name: "monthly", price: { amount: 10 } }], specs: { color: { name: "green" } } },
    result = pick(data, ["section.id", "price.price"]);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

1

If you re already using lodash I do not see a reason to write your own _.pick but that is up to you. Here is how you can do this with lodash in one line or in few with chaining:

let obj = { "section": [{ "id": 1, "name": "dogs" }, { "id": 2, "name": "cats" } ], "price": [{ "name": "monthly", "price": { "amount": 10 } }], "specs": { "color": { "name": "green" } } }

let resultA = _.mapValues(_.omit(obj, ['specs']), a => _.map(a, o => _.pick(o, ['id', 'price'])))

// OR cleaner and more readable with _.chain

let resultB = _(obj)
  .omit(['specs'])
  .mapValues(a => _.map(a, o => _.pick(o, ['id', 'price'])))
  .value()

console.log(resultA)
console.log(resultB)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

The idea is to _.mapValues through the objects and map over the arrays to pick what you need. In this case 'id' and 'price'.

1 Comment

this is a great code but i want a code that takes input as only pick values and not telling it to omit

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.