Hướng dẫn get path of nested object javascript - lấy đường dẫn của đối tượng lồng nhau javascript

Trong chủ đề StackoverFlow này, tôi đã học được bạn có thể nhận được một đường dẫn đối tượng thông qua một chuỗi đơn giản.

Truy cập các đối tượng JavaScript lồng nhau với phím Chuỗi

Xem xét những điều sau:

var person = { name: "somename", personal: { weight: "150", color: "dark" }};

var personWeight = deep_value(person,"personal.weight");

Tôi đang cố gắng xây dựng một mảng các giá trị đối tượng không thuộc loại 'đối tượng' từ đối tượng 'người' của tôi.

Do đó, mảng sẽ giống như:

[['name', []],['personal.weight', []],['personal.color', []]];

Tôi muốn họ nhìn vào hình thức đó bởi vì tôi đã sử dụng thêm cho nó trên đường.

Đó là những gì tôi đã thử:

var toIterate = { name: "somename", personal: { age: "19", color: "dark" } }

var myArray = [];

$.each(toIterate, recursive);

function recursive(key, value) {         

    if (key !== null) {
        myArray.push([key, []]);
    }
    else {
        $.each(value, recursive);
    }
}

console.log(myArray);

Hai mã sau đây đi qua toàn bộ đối tượng, một mảng các đối tượng hoặc một tập hợp cả hai để đưa đường dẫn đến một khóa cụ thể. Có hai phiên bản: Thứ nhất chỉ có đường dẫn đến khóa và thứ hai nhận đường dẫn mà khóa có giá trị đã cho.first gets the path to the key only, and second gets the path where a key has the given value.

Một giải pháp đệ quy tương tự như dưới đây cũng có thể được sử dụng để sửa đổi tất cả các khóa của một đối tượng hoặc mảng các đối tượng được lồng sâu.

1. Nhận đường dẫn đến phím lồng nhau

Mã số

const findPath = (ob, key) => {
  const path = [];
  const keyExists = (obj) => {
    if (!obj || (typeof obj !== "object" && !Array.isArray(obj))) {
      return false;
    }
    else if (obj.hasOwnProperty(key)) {
      return true;
    }
    else if (Array.isArray(obj)) {
      let parentKey = path.length ? path.pop() : "";

      for (let i = 0; i < obj.length; i++) {
        path.push(`${parentKey}[${i}]`);
        const result = keyExists(obj[i], key);
        if (result) {
          return result;
        }
        path.pop();
      }
    }
    else {
      for (const k in obj) {
        path.push(k);
        const result = keyExists(obj[k], key);
        if (result) {
          return result;
        }
        path.pop();
      }
    }
    return false;
  };

  keyExists(ob);

  return path.join(".");
}

Ví dụ

const deeplyNestedObj = {
  a: {
    b: {
      c: {
        d: {
          e: "e",
          f: "f",
          g: {
            G: undefined,
            h: {
              i: {},
              j: {
                k: {
                  K: null,
                  l: {
                    abc: 123,                   
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  e1: {},
  f2: {},
  P1: {
    q1: {
      r1: "r1"
    }
  }
}

console.log(findPath(deeplyNestedObj, "K")); // => a.b.c.d.g.h.j.k
console.log(findPath(deeplyNestedObj, "r1")); // => P1.q1
console.log(findPath(deeplyNestedObj, "gibberish")); // => ""
console.log(findPath(deeplyNestedObj, "helloWorld")); // => ""

Sử dụng trường hợp

So sánh một đường dẫn đã biết cho một đối tượng trong một kiểm tra duy nhất mà không cần nhiều so sánh && hoặc khối thử.Thí dụ:

const errorResponse = {
  status: 403,
  data: {
    user: {
      errorMessage: "You're not authorized to update this user."
    }
  }
};

if(findPath(errorResponse, "errorMessage") === "data.user"){ // true
  //...
} 

2. Nhận đường dẫn đến phím lồng với giá trị đã cho

Với sửa đổi nhẹ, chúng ta có thể làm cho mã trên so sánh giá trị được đưa ra cho khóa.

const findPath = (ob, key, value) => {
  const path = [];
  const keyExists = (obj) => {
    if (!obj || (typeof obj !== "object" && !Array.isArray(obj))) {
      return false;
    }
    else if (obj.hasOwnProperty(key) && obj[key] === value) {
      return true;
    }
    else if (Array.isArray(obj)) {
      let parentKey = path.length ? path.pop() : "";

      for (let i = 0; i < obj.length; i++) {
        path.push(`${parentKey}[${i}]`);
        const result = keyExists(obj[i], key);
        if (result) {
          return result;
        }
        path.pop();
      }
    }
    else {
      for (const k in obj) {
        path.push(k);
        const result = keyExists(obj[k], key);
        if (result) {
          return result;
        }
        path.pop();
      }
    }

    return false;
  };

  keyExists(ob);

  return path.join(".");
}

const deeplyNestedFamilyTree = [ // starts with array
  {
    name: "John",
    children: [{
      name: "Dora",
      children: [{
        name: "Sara"
      }, {
        name: "James"
      }]
    }]
  },
  {
    name: "Scott",
    children: [{
      name: "Smith",
      children: [{
        name: "Brad"
      }, {
        name: "David"
      }]
    }]
  }
]

const deeplyNestedOrgChart = { // starts with object
  position: "CEO",
  subordinates: [
    {
      position: "CFO"
    },
    {
      position: "CTO",
      subordinates: [
        {
          position: "Engineering Lead"
        }
      ]
    },
    {
      position: "COO"
    }
  ]
}


console.log(findPath(deeplyNestedFamilyTree, "name", "John")); 
// => [0]

console.log(findPath(deeplyNestedFamilyTree, "name", "James")); 
// => [0].children[0].children[1]

console.log(findPath(deeplyNestedFamilyTree, "name", "Scott")); 
// => [1]

console.log(findPath(deeplyNestedOrgChart, "position", "Engineering Lead"));
// => subordinates[1].subordinates[0]

Giới hạn

Giới hạn của các mã trên là chúng chỉ trả về đường dẫn đầu tiên được tìm thấy cho một cặp khóa hoặc khóa/giá trị đã cho.

Xem thêm

  • JavaScript: Tìm nếu chuỗi có một trường hợp cụ thể
  • Thay thế tất cả các phím của các đối tượng lồng nhau hoặc mảng các đối tượng trong JavaScript
  • Tính tổng giá trị đầu tư với cổ tức được thêm vào
  • Hạn chế nội dung cho người dùng của các quốc gia cụ thể chỉ có JavaScript
  • Theo dõi số lượng người dùng truy cập với bộ nhớ cục bộ JavaScript
  • React JS Render Form với các trường có điều kiện động
  • React JS Render Form với dữ liệu động từ API phụ trợ