将点表示法转换为括号语法以访问嵌套对象属性。

huangapple go评论76阅读模式
英文:

Convert dot notation to bracket syntax to access nested object properties?

问题

I am outputting data using dot notation and I am trying to convert that dot notation to bracket notation to be able to access the value for that property programatically.

What is the best way to be able to access the nested property of data.person.fullName via data['person']['fullName']

This example is vanilla JS but I it will be TypeScript. I appreciate you looking.

const data = { 
    firstName: 'Jane Doe',
    lastName: 'Doe',
    person: {
        fullName: 'Jane Doe'
    }
}

function outputValue(path) {
    console.log('path passed:', path)
    console.log('value:', data[path])
    const isNested = new RegExp('.').test(path)
    if (isNested) {
        const nestedPath = path.split('.')
        nestedPath.forEach((path) => console.log('path:',path))
    }
    console.log('--------------------------------')
}

outputValue('firstName')
outputValue('person.fullName')
英文:

I am outputting data using dot notation and I am trying to convert that dot notation to bracket notation to be able to access the value for that property programatically.

What is the best way to be able to access the nested property of data.person.fullName via data['person']['fullName']

This example is vanilla JS but I it will be TypeScript. I appreciate you looking.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const data = { 
    firstName: &#39;Jane Doe&#39;,
    lastName: &#39;Doe&#39;,
    person:  {
      fullName: &#39;Jane Doe&#39;
     }
}


function outputValue(path) {
 console.log(&#39;path passed:&#39;, path)
 console.log(&#39;value:&#39;, data[path])
 const isNested = new RegExp(&#39;.&#39;).test(path)
 if (isNested) {
  const nestedPath = path.split(&#39;.&#39;)
  nestedPath.forEach((path) =&gt; console.log(&#39;path:&#39;,path))
  
 }
 console.log(&#39;--------------------------------&#39;)
}



outputValue(&#39;firstName&#39;)
outputValue(&#39;person.fullName&#39;)

<!-- end snippet -->

答案1

得分: 1

You can use String.prototype.indexOf and String.prototype.slice with a recursive sub-call.

Also, I would pass the source object into the function. Accessing a global variable inside the function is bad practice.

const data = {
  firstName: 'Jane',
  lastName: 'Doe',
  person: {
    fullName: 'Jane Doe'
  }
}

function outputValue(obj, path) {
  const index = path.indexOf('.');
  if (index === -1) {
    return obj[path];
  }
  return outputValue(obj[path.slice(0, index)], path.slice(index + 1));
}

console.log(outputValue(data, 'firstName'));
console.log(outputValue(data, 'person.fullName'));

The Lodash library has a _.get function that does just this. It is also way more flexible for some edge cases.

const data = {
  firstName: 'Jane',
  lastName: 'Doe',
  person: {
    fullName: 'Jane Doe'
  }
}

console.log(_.get(data, 'firstName'));
console.log(_.get(data, 'person.fullName'));

Here is a rudimentary TypeScript example that uses iteration:

const data = {
  firstName: 'Jane',
  lastName: 'Doe',
  person: {
    fullName: 'Jane Doe',
  },
  isActive: true
}

// Source: https://dev.to/pffigueiredo/typescript-utility-keyof-nested-object-2pa3
function get<ObjectType, TargetType>(object: ObjectType, path: string): TargetType {
  const keys = path.split('.');
  let result: any = object;
  for (const key of keys) {
    result = result[key];
  }
  return result as TargetType;
}

let r1: string = get(data, 'firstName');
let r2: string = get(data, 'person.fullName');
let r3: boolean = get(data, 'isActive');

; [r1, r2, r3].forEach(r => console.log(r));
英文:

You can use String.prototype.indexOf and String.prototype.slice with a recursive sub-call.

Also, I would pass the source object into the function. Accessing a global variable inside the function is bad practice.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const data = {
  firstName: &#39;Jane&#39;,
  lastName: &#39;Doe&#39;,
  person: {
    fullName: &#39;Jane Doe&#39;
  }
}

function outputValue(obj, path) {
  const index = path.indexOf(&#39;.&#39;)
  if (index === -1) {
    return obj[path]
  }
  return outputValue(obj[path.slice(0, index)], path.slice(index + 1))
}

console.log(outputValue(data, &#39;firstName&#39;))
console.log(outputValue(data, &#39;person.fullName&#39;))

<!-- end snippet -->

The Lodash library has a _.get function that does just this. It is also way more flexible for some edge cases.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const data = {
  firstName: &#39;Jane&#39;,
  lastName: &#39;Doe&#39;,
  person: {
    fullName: &#39;Jane Doe&#39;
  }
}

console.log(_.get(data, &#39;firstName&#39;))
console.log(_.get(data, &#39;person.fullName&#39;))

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

Here is a rudimentary TypeScript example that uses iteration:

const data = {
  firstName: &#39;Jane&#39;,
  lastName: &#39;Doe&#39;,
  person: {
    fullName: &#39;Jane Doe&#39;
  },
  isActive: true
}

// Source: https://dev.to/pffigueiredo/typescript-utility-keyof-nested-object-2pa3
function get&lt;ObjectType, TargetType&gt;(object: ObjectType, path: string): TargetType {
  const keys = path.split(&#39;.&#39;)
  let result: any = object
  for (const key of keys) {
    result = result[key]
  }
  return result as TargetType
}

let r1: string = get(data, &#39;firstName&#39;)
let r2: string = get(data, &#39;person.fullName&#39;)
let r3: boolean = get(data, &#39;isActive&#39;)

; [r1, r2, r3].forEach(r =&gt; console.log(r))

huangapple
  • 本文由 发表于 2023年3月21日 02:27:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75794012.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定