у меня есть этот образец данных,
{
"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()
и не понял массив регистра объектов, он понимает это, если я использовал этот синтаксис «раздел [0]. имя», и я хочу, чтобы он был общим, например «раздел. имя»
Вы можете взять пользовательскую функцию 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.info(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Если вы уже используете 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.info(resultA)
console.info(resultB)
<script src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Идея состоит в том, чтобы _.mapValues
через объекты и отображать массивы на pick
то, что вам нужно. В данном случае «id» и «цена».
это отличный код, но мне нужен код, который принимает входные данные только для выбора значений и не указывает, что его нужно опустить.