динамическая фильтрация объектов с помощью вложенного массива объектов с использованием JavaScript - PullRequest
1 голос
/ 27 мая 2019

у меня есть этот образец данных,

{
    "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() и не понимал массив объекта case, он понимает это, если я использовал этот синтаксис «section [0] .name» и я хочу, чтобы он был универсальным, как «section.name»

Ответы [ 2 ]

2 голосов
/ 27 мая 2019

Вы можете использовать пользовательскую функцию 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 голос
/ 28 мая 2019

Если вы уже используете 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» и «цена».

...