从嵌套JSON对象数组中任何给定子对象的直接父对象获取值



这是我的JSON示例。

const data = [{
"employees": [ 
{         
"employee": [
{
"name": "Jon",
"surname": "Smith",
"leaveRequest": [
{
"id": "3000",
"approver": "Terry"
}
]
}],
},
{
"employee": [
{
"name": "Mike",
"surname": "Jones",
"leaveRequest": [
{
"id": "1700",
"approver": "Mary"
}
]
},
]
}
]
}];

我希望能够在所有离职申请中按id进行搜索,并获得员工的姓名。

如果我通过id";3000〃;我希望能够得到一个对象["名称":"乔恩","姓氏":"史密斯"]

我尝试过实现以下解决方案:如何在嵌套json对象的数组中获取子Id的直接父Id?

这就是我尝试过的:

const findEmployee = (arr, id) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id === id) {
return [];
} 
else if (arr[i].employee && arr[i].employee.length) {
const t = findEmployee(arr[i].employee, id);
if (t !== false) {
if (t.length == 0) 
t.push({"name": arr[i].name, "surname": arr[i].surname});
return t;
}
}
}
return false;
};
console.log(findEmployee(data, "3000"))

但该线程中的解决方案依赖于每个子节点都有相同的密钥"children",这在我的场景中是不起作用的。我必须将我的JSON结构重组为:

employee
employee
employee
id

这在我看来是没有道理的。如何在所有离职申请中按id搜索,并从直系亲属那里获得员工的姓名?

我建议递归遍历对象,如果找到具有leaveRequest属性的对象,则返回。

一旦找到它,我们将去掉leaveRequest并返回对象的其余部分。

编辑:这将适用于每个员工的多个休假请求。

const data = [{ "employees": [ { "employee": [ { "name": "Jon", "surname": "Smith", "leaveRequest": [ { "id": "2990", "approver": "Kim" } , { "id": "3000", "approver": "Terry" } ] }], }, { "employee": [ { "name": "Mike", "surname": "Jones", "leaveRequest": [  { "id": "1200", "approver": "Jane" }, { "id": "1700", "approver": "Mary" } ] }, ] } ] }]; 
function findRequest(input, id) {
if (input.leaveRequest && input.leaveRequest.find(lr => lr.id == id)) {
// Return everything bar the leave request...
return (({ leaveRequest, ...obj}) => obj)(input);
}
for(let k in input) {
if (input[k] && typeof(input[k]) === 'object') {
let leaveRequest = findRequest(input[k], id);
if (leaveRequest) return leaveRequest;
}
}
}
let ids = [1700, 3000];
ids.forEach(id => console.log('id: ', id, 'nrequest:', findRequest(data, id)));
.as-console-wrapper { max-height: 100% !important; }

以下是使用对象扫描的答案:

.as-console-wrapper {max-height: 100% !important; top: 0}
<script type="module">
import objectScan from 'https://cdn.jsdelivr.net/npm/object-scan@18.3.0/lib/index.min.js';
const data = [{ employees: [{ employee: [{ name: 'Jon', surname: 'Smith', leaveRequest: [{ id: '3000', approver: 'Terry' }] }] }, { employee: [{ name: 'Mike', surname: 'Jones', leaveRequest: [{ id: '1700', approver: 'Mary' }] }] }] }];
const find = objectScan(['[*].employees[*].employee[*].leaveRequest[*].id'], {
abort: true, // abort after first result
filterFn: ({ value, context }) => value === context, // find the correct id
rtn: ({ parents }) => parents[2] // return the correct node
});
console.log(find(data, '3000'));
// => { name: 'Jon', surname: 'Smith', leaveRequest: [ { id: '3000', approver: 'Terry' } ] }
</script>

免责声明:我是物体扫描的作者

挑战的一部分是数据的形状很奇怪,对象包含单元素数组,数组包含单键对象。首先,我会将数据重塑为更合理的数据(假设数据不是递归的——员工不包含其他员工(。

// create a flat array of employees [ employeeA, employeeB, ...
const employees = data[0].employees.map(object => object.employee[0]);

这样,从leaveRequestid到包含员工的方法就是建立索引。这里,另一个假设是leaveRequest ID是唯一的。

// create an index { leaveIdX: employeeC, leaveIdY: employeeD, ...
const leaveRequestIndex = employees.reduce((index, employee) => {
employee.leaveRequest.forEach(request => index[request.id] = employee);
return index;
}, {});

这提供了从leaveRequest到employee的O(1(查找,如下所示。。。

// given someLeaveRequestId, get the containingEmployee
const containingEmployee = leaveRequestIndex[someLeaveRequestId];

正在测试OP数据。。。

// create a flat array of employees [ { employee }, { employee }, ...
const employees = data()[0].employees.map(object => object.employee[0]);
// create an index { leaveId: { employee }, leaveId: { employee }, ...
const leaveRequestIndex = employees.reduce((index, employee) => {
employee.leaveRequest.forEach(request => index[request.id] = employee);
return index;
}, {});
// test it: which employee has leave request 3001?
const employee = leaveRequestIndex[3001];
const { name, surname } = employee;
console.log(name, surname);

function data() {
return [{
"employees": [ 
{         
"employee": [
{
"name": "Jon",
"surname": "Smith",
"leaveRequest": [
{
"id": "3000",
"approver": "Terry"
},
{
"id": "3001",
"approver": "Larry"
}
]
}],
},
{
"employee": [
{
"name": "Mike",
"surname": "Jones",
"leaveRequest": [
{
"id": "1700",
"approver": "Mary"
}
]
},
]
}
]
}];
}

最新更新