每次加载应用程序时,都会收到以下json
:
[
{
id: 'mALRRY93jASr',
identifier: '100',
text: 'Text A'
},
{
id: '7S3xHZEdNcfV',
identifier: '200',
text: 'Text B'
},
{
id: '2ZA5xSJeukU6',
identifier: '300',
text: 'Text C',
},
{
id: 'bhg3GnLEvw2k',
identifier: '300.100',
text: 'Text C - A'
},
{
id: 'bhg3GnLEvw2k',
identifier: '300.100.100',
text: 'Text C - A - A'
},
{
id: '2AcXNr4HT388',
identifier: '300.200',
text: 'Text C - B'
}
]
树级别由identifier
属性标识。
这棵树可以有数千个孩子,所以它需要递归。
如何使用Lodash排列json
使其看起来像下面的json
?
[
{
id: 'mALRRY93jASr',
identifier: '100',
text: 'Text A'
},
{
id: '7S3xHZEdNcfV',
identifier: '200',
text: 'Text B'
},
{
id: '2ZA5xSJeukU6',
identifier: '300',
text: 'Text C',
children: [
{
id: 'bhg3GnLEvw2k',
identifier: '300.100',
text: 'Text C - A',
children: [
{
id: 'bhg3GnLEvw2k',
identifier: '300.100.100',
text: 'Text C - A - A'
}
]
},
{
id: '2AcXNr4HT388',
identifier: '300.200',
text: 'Text C - B'
}
]
}
]
答案 0 :(得分:1)
您可以采用迭代方法,在identifier
的同一路径中查找对象并构建嵌套结构。
这种方法也适用于未排序的数据。
var data = [{ id: 'mALRRY93jASr', identifier: '100', text: 'Text A' }, { id: '7S3xHZEdNcfV', identifier: '200', text: 'Text B' }, { id: '2ZA5xSJeukU6', identifier: '300', text: 'Text C' }, { id: 'bhg3GnLEvw2k', identifier: '300.100', text: 'Text C - A' }, { id: 'bhg3GnLEvw2k', identifier: '300.100.100', text: 'Text C - A - A' }, { id: '2AcXNr4HT388', identifier: '300.200', text: 'Text C - B' }],
tree = [];
data.reduce((r, o) => {
o.identifier
.split('.')
.map((_, i, a) => a.slice(0, i + 1).join('.'))
.reduce((q, identifier, i, { length }) => {
var temp = (q.children = q.children || []).find(p => p.identifier === identifier);
if (!temp) {
q.children.push(temp = { identifier });
}
if (i + 1 === length) {
Object.assign(temp, o);
}
return temp;
}, r);
return r;
}, { children: tree });
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:0)
我以previous answer of mine为基础。有很多相似之处,但是您的“路径”语法有点不同,因此我不得不调整一些解析。
const data = [
{
id: 'mALRRY93jASr',
identifier: '100',
text: 'Text A'
},
{
id: '7S3xHZEdNcfV',
identifier: '200',
text: 'Text B'
},
{
id: '2ZA5xSJeukU6',
identifier: '300',
text: 'Text C',
},
{
id: 'bhg3GnLEvw2k',
identifier: '300.100',
text: 'Text C - A'
},
{
id: 'bhg3GnLEvw2k',
identifier: '300.100.100',
text: 'Text C - A - A'
},
{
id: '2AcXNr4HT388',
identifier: '300.200',
text: 'Text C - B'
}
];
const pathPartRegex = /.*?\./g;
const tree = _.reduce(data, (result, value) => {
// We use the . character as a "path part" terminator,
// but it is not there at the end of the string, so we add it
let identifier = value.identifier;
if (!identifier.endsWith(".")) {
identifier = identifier + ".";
}
const pathParts = identifier.match(pathPartRegex);
let node = result;
let path = "";
// Go down through tree until last path part
const notLastPart = pathParts.splice(0, pathParts.length - 1);
for (const pathPart of notLastPart) {
path += pathPart;
const existingNode = node.children
? node.children.find(item => path.startsWith(item.identifier) )
: node.find(item => path.startsWith(item.identifier));
if (existingNode) {
node = existingNode
} else {
// If we need to traverse over a path that doesn't exist, just create it
// See notes
const newNode = {
identifier: path,
children: []
};
// The root element is just an array, and doesn't have a children property
if (node.children) {
node.children.push(newNode);
} else {
node.push(newNode);
}
node = newNode;
}
}
// Add new node
const newNode = {
id: value.id,
text: value.text,
identifier: value.identifier,
children: []
};
// The root element is just an array, and doesn't have a children property
if (node.children) {
node.children.push(newNode);
} else {
node.push(newNode);
}
return result;
}, []);
通过RunKit(https://npm.runkit.com/lodash)进行了测试
注意:
与原始答案相同的警告也适用于此。
答案 2 :(得分:0)
您可以使用Array.reduce()
和_.setWith()
通过路径(身份)创建对象树。然后,您可以对_.transform()
使用递归函数,并使用_.values()
将select order_id, a, b, c
from summary
where a > 0 and (a + b + c + d > 2 * b)
转换为数组:
children
const createTree = (arr) => {
// reduce to a tree of objects
const oTree = arr.reduce((r, o) => {
const key = o.identifier.replace(/\./g, '.children.');
// creates the path and adds the object value
return _.setWith(r, key, o, Object)
}, {});
// transforms the children to an array recursivly
const transformChildren = (tree) =>
_.transform(tree, (acc, v, k) => {
const value = _.isObject(v) ? transformChildren(v) : v;
acc[k] = _.eq(k, 'children') ? _.values(value) : value;
});
return transformChildren(_.values(oTree));
};
const data = [{"id":"mALRRY93jASr","identifier":"100","text":"Text A"},{"id":"7S3xHZEdNcfV","identifier":"200","text":"Text B"},{"id":"2ZA5xSJeukU6","identifier":"300","text":"Text C"},{"id":"bhg3GnLEvw2k","identifier":"300.100","text":"Text C - A"},{"id":"bhg3GnLEvw2k","identifier":"300.100.100","text":"Text C - A - A"},{"id":"2AcXNr4HT388","identifier":"300.200","text":"Text C - B"}];
const result = createTree(data);
console.log(result);