使用javascript使用嵌套的对象数组进行对象动态过滤

时间:2019-05-27 10:16:20

标签: javascript node.js lodash

我有这个数据样本,

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

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

我想从该对象中选择一些属性,

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

它应该提供一个对象:

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

我尝试了lodash.pick()并且不了解对象大小写的数组,如果我使用了这种语法“ section [0] .name”并且希望它是通用的,例如“ section.name”,它就可以理解。 / p>

2 个答案:

答案 0 :(得分:2)

您可以使用自定义的pick函数,该函数具有所需的属性,并且可以获取所有嵌套数组,而不必成为路径的一部分。

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; }

答案 1 :(得分:1)

如果您已经在使用lodash,那么我看不出编写自己的_.pick的理由,但这取决于您。这是使用lodash一行或几行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>

这个想法是_.mapValues遍历对象并将数组映射到pick您所需要的。在这种情况下,“ id”和“ price”。