簡體   English   中英

從嵌套 JSON 對象數組中的任何給定子級的直接父級獲取值?

[英]Get values from immediate parent for any given child in array of nested JSON objects?

這是我的 JSON 的樣本。

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

我希望能夠在所有 leaveRequests 中按 id 搜索並獲取員工的姓名和姓氏。

如果我通過 id "3000" 我希望能夠獲得 object ["name": "Jon", "surname": "Smith"]

我已經嘗試實施解決方案: 如何在嵌套 json Object 的數組中獲取子 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"))

但是該線程中的解決方案依賴於每個子節點具有相同的鍵“孩子”,這在我的場景中不起作用。 我必須將我的 JSON 結構重組為:

employee
    employee
       employee
          id

這在我的場景中沒有意義。 如何在所有 leaveRequests 中按 id 搜索並從直系父母那里獲取員工的姓名和姓氏?

我建議遞歸遍歷 object,如果我們找到帶有leaveRequest屬性的 object 則返回。

一旦我們找到這個,我們將去掉 leaveRequest 並返回 object 的 rest。

 const data = [{ "employees": [ { "employee": [ { "name": "Jon", "surname": "Smith", "leaveRequest": [ { "id": "3000", "approver": "Terry" } ] }], }, { "employee": [ { "name": "Mike", "surname": "Jones", "leaveRequest": [ { "id": "1700", "approver": "Mary" } ] }, ] } ] }]; function findRequest(input, id) { if (input.leaveRequest && input.leaveRequest[0].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 }

這是使用object-scan的答案:

 .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>

免責聲明:我是對象掃描的作者

部分挑戰是數據形狀奇怪,對象包含單元素 arrays 和 arrays 包含單鍵對象。 我首先將數據重塑為更合理的東西(假設數據不是遞歸的——員工不包含其他員工)。

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

這樣,從leaveRequest id到包含員工的 go 的方法是建立一個索引。 這里,另一個假設是 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 到員工的 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" } ] }, ] } ] }]; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM