我有这个JavaScript对象:
const object = {
categories: [
{
title: 'Category 1',
items: [
{ title: 'Item 1', image: 'path/to/file-1.png' },
{ title: 'Item 2', image: 'path/to/file-2.png' },
{ title: 'Item 3', image: 'path/to/file-3.png' }
]
},
{
title: 'Category 2',
items: [
{ title: 'Item 4', image: 'path/to/file-4.png' },
{ title: 'Item 5', image: 'path/to/file-5.png' },
{ title: 'Item 6', image: 'path/to/file-6.png' }
]
}
]
}
我只能使用Lodash的_.get
方法选择一项。
_.get(object, 'categories[0].items[0].image')
// => "path/to/file-1.png"
但是我需要一个包含所有出现的数组,而不仅仅是从位置0开始。类似这样的东西:
_.get(object, 'categories[].items[].image')
// => ["path/to/file-1.png", "path/to/file-2.png", "path/to/file-3.png", "path/to/file-4.png", "path/to/file-5.png", "path/to/file-6.png"]
是否可以使用Lodash做到这一点?
如果不可能,您是否知道如何实施?
编辑:我正在从Lodash寻找类似_.get
的东西,我可以在其中提供“搜索模式”(路径)作为字符串。显然,我知道如何使用map
,reduce
等来解决这个问题。
答案 0 :(得分:2)
使用flatMap
相当容易,不需要任何库:
const object = {
categories: [
{
title: 'Category 1',
items: [
{ title: 'Item 1', image: 'path/to/file-1.png' },
{ title: 'Item 2', image: 'path/to/file-2.png' },
{ title: 'Item 3', image: 'path/to/file-3.png' }
]
},
{
title: 'Category 2',
items: [
{ title: 'Item 4', image: 'path/to/file-4.png' },
{ title: 'Item 5', image: 'path/to/file-5.png' },
{ title: 'Item 6', image: 'path/to/file-6.png' }
]
}
]
};
const images = object.categories.flatMap(({ items }) => items.map(({ image }) => image));
console.log(images);
或者,用reduce
:
const object = {
categories: [
{
title: 'Category 1',
items: [
{ title: 'Item 1', image: 'path/to/file-1.png' },
{ title: 'Item 2', image: 'path/to/file-2.png' },
{ title: 'Item 3', image: 'path/to/file-3.png' }
]
},
{
title: 'Category 2',
items: [
{ title: 'Item 4', image: 'path/to/file-4.png' },
{ title: 'Item 5', image: 'path/to/file-5.png' },
{ title: 'Item 6', image: 'path/to/file-6.png' }
]
}
]
};
const images = object.categories.reduce((a, { items }) => {
items.forEach(({ image }) => {
a.push(image);
});
return a;
}, []);
console.log(images);
答案 1 :(得分:1)
这是我对flatGet
函数的实现,该函数可以处理数组:
const flatGet = (object, path) => {
const p = path.match(/[^.\[\]]+/g)
const getItem = (item, [current, ...path]) => {
if(current === undefined) return item
if(typeof item !== 'object') return undefined
if(Array.isArray(item)) return item.flatMap(o => getItem(o[current], path))
return getItem(item[current], path)
}
return getItem(object, p)
}
const object = {"categories":[{"title":"Category 1","items":[{"title":"Item 1","image":"path/to/file-1.png"},{"title":"Item 2","image":"path/to/file-2.png"},{"title":"Item 3","image":"path/to/file-3.png"}]},{"title":"Category 2","items":[{"title":"Item 4","image":"path/to/file-4.png"},{"title":"Item 5","image":"path/to/file-5.png"},{"title":"Item 6","image":"path/to/file-6.png"}]}]}
var result = flatGet(object, 'categories.items.image')
console.log(result)
答案 2 :(得分:0)
我们现在对这些类型的查询使用object-scan。它非常强大(一旦您将头围起来),并且足够容易用于基本内容。这是解决问题的方法
const objectScan = require('object-scan');
const object = {
categories: [
{
title: 'Category 1',
items: [
{ title: 'Item 1', image: 'path/to/file-1.png' },
{ title: 'Item 2', image: 'path/to/file-2.png' },
{ title: 'Item 3', image: 'path/to/file-3.png' }
]
},
{
title: 'Category 2',
items: [
{ title: 'Item 4', image: 'path/to/file-4.png' },
{ title: 'Item 5', image: 'path/to/file-5.png' },
{ title: 'Item 6', image: 'path/to/file-6.png' }
]
}
]
};
const r = objectScan(['categories[*].items[*].image'], { rtn: 'value' })(object);
console.log(r);
// => [ 'path/to/file-6.png', 'path/to/file-5.png', 'path/to/file-4.png',
// 'path/to/file-3.png', 'path/to/file-2.png', 'path/to/file-1.png' ]
答案 3 :(得分:-1)
这是我的实现,可以处理[]
路径:
const object = { categories: [ { title: "Category 1", items: [ { title: "Item 1", image: "path/to/file-1.png" }, { title: "Item 2", image: "path/to/file-2.png" }, { title: "Item 3", image: "path/to/file-3.png" } ] }, { title: "Category 2", items: [ { title: "Item 4", image: "path/to/file-4.png" }, { title: "Item 5", image: "path/to/file-5.png" }, { title: "Item 6", image: "path/to/file-6.png" } ] } ] };
const object2 = { categories: { title: "Category 1" } };
function flatGet(object, path) {
const pathArray = path.split(".");
while (pathArray.length > 0) {
let pos = pathArray.shift();
if (pos.includes("[]")) {
pos = pos.slice(0, -2);
}
if (Array.isArray(object)) {
object = object.reduce((acc, cur) => acc.concat(cur[pos]), []);
} else {
object = object[pos];
}
}
return object;
}
var res = flatGet(object, "categories[].items[].image"); // ["path/to/file-1.png", ...]
var res2 = flatGet(object2, "categories.title"); // "Category 1"
之前编辑过:
因为您需要获取images
数组,所以map
可以帮助您。这是一个简单的例子:
_.map(object.categories[0].items, o => _.get(o, 'image'))
// if categories[0].items is not always there, just use another get:
_.map(_.get(object, 'categories[0].items'), o => _.get(o, 'image'))