कैसे कन्वर्ट करने के लिए इस वृक्ष संरचना में एक जे एस MemberExpression वृक्ष संरचना?

0

सवाल

मैं एक तरह से बाहर सोचा का प्रतिनिधित्व करने के लिए अभिव्यक्ति a.b[c.d][e].f[g[h[i.j]]] का उपयोग अपने स्वयं के पेड़ के प्रारूप में है. कि अभिव्यक्ति का प्रतिनिधित्व करती है, एक पेड़ के रूप में, इस तरह दिखता है:

{
  "form": "nest",
  "link": [
    {
      "form": "site",
      "name": "a"
    },
    {
      "form": "site",
      "name": "b"
    },
    {
      "form": "nest",
      "link": [
        {
          "form": "site",
          "name": "c"
        },
        {
          "form": "site",
          "name": "d"
        }
      ]
    },
    {
      "form": "nest",
      "link": [
        {
          "form": "site",
          "name": "e"
        }
      ]
    },
    {
      "form": "site",
      "name": "f"
    },
    {
      "form": "nest",
      "link": [
        {
          "form": "site",
          "name": "g"
        },
        {
          "form": "nest",
          "link": [
            {
              "form": "site",
              "name": "h"
            },
            {
              "form": "nest",
              "link": [
                {
                  "form": "site",
                  "name": "i"
                },
                {
                  "form": "site",
                  "name": "j"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

अब, कि एक ही स्ट्रिंग अभिव्यक्ति भी है द्वारा प्रतिनिधित्व किया, यह जे एस AST वृक्ष संरचना के लिए MemberExpression:

{
  "type": "MemberExpression",
  "object": {
    "type": "MemberExpression",
    "object": {
      "type": "MemberExpression",
      "object": {
        "type": "MemberExpression",
        "object": {
          "type": "MemberExpression",
          "object": {
            "type": "Identifier",
            "name": "a"
          },
          "property": {
            "type": "Identifier",
            "name": "b"
          },
          "computed": false
        },
        "property": {
          "type": "MemberExpression",
          "object": {
            "type": "Identifier",
            "name": "c"
          },
          "property": {
            "type": "Identifier",
            "name": "d"
          },
          "computed": false
        },
        "computed": true
      },
      "property": {
        "type": "Identifier",
        "name": "e"
      },
      "computed": true
    },
    "property": {
      "type": "Identifier",
      "name": "f"
    },
    "computed": false
  },
  "property": {
    "type": "MemberExpression",
    "object": {
      "type": "Identifier",
      "name": "g"
    },
    "property": {
      "type": "MemberExpression",
      "object": {
        "type": "Identifier",
        "name": "h"
      },
      "property": {
        "type": "MemberExpression",
        "object": {
          "type": "Identifier",
          "name": "i"
        },
        "property": {
          "type": "Identifier",
          "name": "j"
        },
        "computed": false
      },
      "computed": true
    },
    "computed": true
  },
  "computed": true
}

तो उन दो वृक्ष संरचनाओं का प्रतिनिधित्व करते हैं, एक ही स्ट्रिंग अभिव्यक्ति a.b[c.d][e].f[g[h[i.j]]]. तुम नोटिस हूँ पहली पर "घोंसला" संरचना, वहाँ रहे हैं दो प्रकार की वस्तुओं, साइटों और घोंसले. एक साइट सिर्फ एक नाम है, जबकि एक घोंसला अर्थ है "गणना" संपत्ति में जे एस AST शब्दावली है. तो एक घोंसले की तरह है parent[this_is_a_nest[and_another_nest]]है , जबकि parent.site1.site2.

कैसे आप को बदलने के पहले वृक्ष संरचना में एक दूसरे के?

क्या मैं इतनी दूर नहीं है, वास्तव में वहाँ हो रही है, यह काफी भ्रामक है.

console.log(JSON.stringify(transform(getNest()), null, 2))

function transform(nest) {
  let i = 0
  let stack = []
  while (i < nest.link.length) {
    let object = nest.link[i++]
    let property = nest.link[i]
    let member = {
      type: 'MemberExpression'
    }
    stack.push(member)

    if (object.form === 'nest') {
      member.object = transform(object)
    } else {
      member.object = {
        type: 'Identifier',
        name: object.name
      }
    }

    if (property) {
      if (property.form === 'nest') {
        member.property = transform(property)
        member.computed = true
      } else {
        member.property = {
          type: 'Identifier',
          name: property.name
        }
      }
    }
  }

  let object = stack.pop()
  while (stack.length) {
    let nextObject = stack.pop()
    nextObject.object = object
    object = nextObject
  }

  return object
}


function getNest() {
  return {
    "form": "nest",
    "link": [
      {
        "form": "site",
        "name": "a"
      },
      {
        "form": "site",
        "name": "b"
      },
      {
        "form": "nest",
        "link": [
          {
            "form": "site",
            "name": "c"
          },
          {
            "form": "site",
            "name": "d"
          }
        ]
      },
      {
        "form": "nest",
        "link": [
          {
            "form": "site",
            "name": "e"
          }
        ]
      },
      {
        "form": "site",
        "name": "f"
      },
      {
        "form": "nest",
        "link": [
          {
            "form": "site",
            "name": "g"
          },
          {
            "form": "nest",
            "link": [
              {
                "form": "site",
                "name": "h"
              },
              {
                "form": "nest",
                "link": [
                  {
                    "form": "site",
                    "name": "i"
                  },
                  {
                    "form": "site",
                    "name": "j"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}

सच में पता नहीं कैसे करने के लिए समस्या को आसान बनाने के नीचे एक तरह से इसे हल करने के लिए अभी तक है.

मुझे नहीं पता अगर यह है किसी भी मदद की (acornjs पार्सर के लिए MemberExpression).

3

सबसे अच्छा जवाब

1

यह यह करना चाहिए:

function transform(treeNode) {
  if (treeNode.form == "site") {
    return {
      "type": "Identifier",
      "name": treeNode.name,
    };
  } else if (treeNode.form == "nest") {
    const [base, ...props] = treeNode.link;
    console.assert(base.form == "site");
    return props.reduce((lhs, rhs) => {
      if (rhs.form == "nest") {
        return {
          "type": "MemberExpression",
          "object": lhs,
          "property": transform(rhs), // returns MemberExpression or (if singleton) Identifier
          "computed": true,
        };
      } else if (rhs.form == "site") {
        return {
          "type": "MemberExpression",
          "object": lhs,
          "property": transform(rhs), // returns Identifier
          "computed": false,
        };
      }
    }, transform(base));
  }
}

आप कर सकते हैं के पाठ्यक्रम को आसान बनाने reducer के लिए बस

props.reduce((lhs, rhs) => ({
  "type": "MemberExpression",
  "object": lhs,
  "property": transform(rhs),
  "computed": rhs.form == "nest",
}), transform(base));
2021-11-23 13:35:06

कोई रास्ता नहीं! आप सरलीकृत है कि करने के लिए नीचे अपने नंगे सार! मैं वास्तव में लगता है कि मैं सिर्फ यह मिल गया भी, मैं जा रहा हूँ करने के लिए पोस्ट मेरे जवाब के रूप में अच्छी तरह से :D
Lance Pollard

तो क्या था अपनी तकनीक, कैसे किया था आप यह समझ से बाहर इतने सुंदर ढंग से? मैं कहना है कि यह काफी मुश्किल है । मूल रूप से, कैसे क्या मैं जानने के लिए किया जा करने के लिए क्या और अधिक की तरह तुम किया था :)
Lance Pollard

@LancePollard सोच कार्यात्मक और grokking प्रत्यावर्तन में मदद करता है. यह मेरे लिए स्पष्ट था कि यह था करने के लिए एक समारोह है, नहीं एक ढेर का उपयोग कर और पाश (हालांकि मैं वास्तव में नहीं था यहां तक कि पूरी तरह से कोड को पढ़ने के अपने प्रयास). और वहाँ दो दिशाओं के चंक्रमण: एक नीचे एक संपत्ति की चेन, अन्य में नेस्टेड भाव । को देखते हुए, श्रृंखला रैखिक है, हो जाएगा कि एक सरल गुना से अधिक सरणी उत्पन्न करने के लिए नेस्टेड MemberExpression लिंक की गई सूची के लिए, घोंसले के शिकार के प्रत्यावर्तन के लिए आवश्यक है । तो यह सिर्फ एक सवाल था कि क्या की कम छोड़ दिया है या सही करने के लिए कैसे और विशेष मामले के साथ शुरू
Bergi
1

एक छोटी पुनरावर्ती समाधान:

function mem_tree(objs){
    var o = null;
    for (var obj of objs){
       if (obj.form === 'site'){
          o = (o === null) ? {type:"Identifier", name:obj.name} : {type: "MemberExpression", object:o, property:{type:"Identifier", name:obj.name}, computed:false}
       }
       else{
          var r = mem_tree(obj.link);
          o = (o === null) ? {object:r} : {type: "MemberExpression", object:o, property:r, computed:true}
       }
    }
    return o;
}
var d = {'form': 'nest', 'link': [{'form': 'site', 'name': 'a'}, {'form': 'site', 'name': 'b'}, {'form': 'nest', 'link': [{'form': 'site', 'name': 'c'}, {'form': 'site', 'name': 'd'}]}, {'form': 'nest', 'link': [{'form': 'site', 'name': 'e'}]}, {'form': 'site', 'name': 'f'}, {'form': 'nest', 'link': [{'form': 'site', 'name': 'g'}, {'form': 'nest', 'link': [{'form': 'site', 'name': 'h'}, {'form': 'nest', 'link': [{'form': 'site', 'name': 'i'}, {'form': 'site', 'name': 'j'}]}]}]}]}
var result = mem_tree(d.link)
2021-11-24 05:25:09
0

मैं सिर्फ इस हल के बाद थोड़ा @Bergi के जवाब इससे पहले कि मैं इसे देखा था, इतना उत्तेजित हो!

function transform(nest) {
  let i = 0
  let stack = [{
    type: 'Identifier',
    name: nest.link[i++].name
  }]
  while (i < nest.link.length) {
    const object = stack.shift()
    const node = nest.link[i++]
    if (node.form === 'nest') {
      const property = transform(node)
      stack.push({
        object: object,
        property,
        computed: true
      })
    } else {
      let property = {
        type: 'Identifier',
        name: node.name
      }
      stack.push({
        object: object,
        property: property,
        computed: false
      })
    }
  }

  return stack.shift()
}

आउटपुट है:

{
  "object": {
    "object": {
      "object": {
        "object": {
          "object": {
            "type": "Identifier",
            "name": "a"
          },
          "property": {
            "type": "Identifier",
            "name": "b"
          },
          "computed": false
        },
        "property": {
          "object": {
            "type": "Identifier",
            "name": "c"
          },
          "property": {
            "type": "Identifier",
            "name": "d"
          },
          "computed": false
        },
        "computed": true
      },
      "property": {
        "type": "Identifier",
        "name": "e"
      },
      "computed": true
    },
    "property": {
      "type": "Identifier",
      "name": "f"
    },
    "computed": false
  },
  "property": {
    "object": {
      "type": "Identifier",
      "name": "g"
    },
    "property": {
      "object": {
        "type": "Identifier",
        "name": "h"
      },
      "property": {
        "object": {
          "type": "Identifier",
          "name": "i"
        },
        "property": {
          "type": "Identifier",
          "name": "j"
        },
        "computed": false
      },
      "computed": true
    },
    "computed": true
  },
  "computed": true
}
2021-11-23 13:45:28

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में