如何创建这个复杂的 Javascript 变量

How do I create this complex Javascript variable

提问人:Marcos Camargo 提问时间:11/17/2023 最后编辑:Marcos Camargo 更新时间:11/17/2023 访问量:77

问:

我想创建一个复杂的 Javascript 变量,如下所示:

var e = {record: {role: {individual: {tag: value}}}};

其中 record、role、individual 和 value 是来自数组的变量。 最后,它应该看起来像这样:

var e = {1: {2: {1: {name: Joseph Quincy}
                    {age: 20}    

                 2: {name: Mary Poppins}
                    {age: 40}

                 3: {name: Sebastian Quincy}
                    {age: 60}

            {3: {1: ... and so forth

该数组派生自如下所示的数据,其中第一个数字是记录,第二个数字是角色,第三个数字是个人,标签是名称和年龄,值在空格之后:

name_1_2_1 Joseph Jones
name_1_2_2 Mary Poppins
name_1_2_3 Sebastian Quincy
age_1_2_1 20
age_1_2_2 40
age_1_2_3 60

这些数组看起来像 Joseph Jones name_1_2_1:

key_value_ary = (name_1_2_1, Joseph James);
tag_rri_ary = (name, _1_2_1);
r_r_i_ary = (1, 2, 1);

因此

value      = key_value_ary[1]; -> Joseph Jones
tag        = tag_rri_ary[0];   -> name
record     = r_r_i_ary[0];     -> 1
role       = r_r_i_ary[1];     -> 2
individual = r_r_i_ary[2];     -> 1

我已经创建了所有这些对象,但我不知道如何写入最终变量“e”。 我有下面的代码可以找出不同的值。我一次只写一行,因此记录可能已经存在于上一个条目中。

if (r_r_i_ary.length == 3) {
        var tag = tag_rri_ary[0];
        console.log("TAG", tag);
        var value = key_value_ary[1];
        console.log("VALUE", value);
        const a = {};
        a[tag] = value; // tag value
        console.log("AAA", a);
        const b = {};
        var individual = r_r_i_ary[2]; // individual
        b[individual] = a;
        console.log("BBB", b);
        const c = {};
        var role = r_r_i_ary[1]; // role
        c[role] = b;
        console.log("CCC", c);
        const d = {};
        var record = r_r_i_ary[0]; // record
        d[record] = c;
        console.log("DDD", d);
        e=????? 
      }

我从控制台获得了它作为示例之一,但我需要将所有变量连接在一起:

{
    "4": {
        "1": {
            "2": {
                "will_plac": "Atibaia, São Paulo, Brasil"
            }
        }
    }
}

我该怎么做?

谢谢!

JavaScript 对象

评论

0赞 tkausl 11/17/2023
不正是你要找的对象吗?d
0赞 cyberbrain 11/17/2023
您能否通过添加数组的一些初始化来使其成为一个最小的可重现示例,并且?我真的不确定这三者是如何构建和协同工作的。r_r_i_arytag_rri_arykey_value_ary
0赞 Marcos Camargo 11/17/2023
d 不是因为它每次都覆盖。一个角色中有多个人,一个记录中有多个角色。我不知道如何在不破坏变量“e”的情况下继续添加更多变量。
0赞 cyberbrain 11/17/2023
你也许真的想拥有吗?var e = [{record: [{role: [{individual: [{tag: value}]}]}]}];
0赞 Marcos Camargo 11/17/2023
@cyberbrain 我不希望有数组,而只是对象。

答:

1赞 Valery 11/17/2023 #1

// Will use named capturing groups to parse each line
const lineRegex = new RegExp(
  "^(?<tag>\\w+)" +        // Match and capture the tag in the beginning of the line (word characters)
  "_(?<record>\\d+)" +     // Match and capture the record (digits)
  "_(?<role>\\d+)" +       // Match and capture the role (digits)
  "_(?<individual>\\d+)" + // Match and capture the individual (digits)
  "\\s+" +                 // Match one or more whitespace characters
  "(?<value>.+)$"          // Match and capture the value (any characters until the end of the line)
);

function parse(input) {
  return input
    // get each line separately
    .split('\n')
    // parse it with a regex
    .map((line) => line.match(lineRegex).groups)
    // reduce the parsed lines to the required shape
    .reduce((agg, parsed) => {
      const out = {...agg};
      if (typeof out[parsed.record] === 'undefined') {
        // Make sure there is a record to append to
        out[parsed.record] = {};
      }
      if (typeof out[parsed.record][parsed.role] === 'undefined') {
        // Make sure there is a role in the record to append to
        out[parsed.record][parsed.role] = {};
      }
      if (typeof out[parsed.record][parsed.role][parsed.individual] === 'undefined') {
        // Make sure there is an individual to assign values to
        out[parsed.record][parsed.role][parsed.individual] = {};
      }
      
      // Store the actual value for the tag
      out[parsed.record][parsed.role][parsed.individual][parsed.tag] = parsed.value;
      return out;
    }, {});
}

const data = `name_1_2_1 Joseph Jones
name_1_2_2 Mary Poppins
name_1_2_3 Sebastian Quincy
age_1_2_1 20
age_1_2_2 40
age_1_2_3 60`;

console.log(parse(data));

评论

0赞 Marcos Camargo 11/17/2023
谢谢!它有效。out ={...agg}
1赞 Djave 11/17/2023 #2

与 Valery 类似,但首先我将数据结构化为一种有用的方式:

[
  {
    "route": [
      "1",
      "2",
      "3"
    ],
    "key": "age",
    "val": "60"
  }
]

使用和其他基本数组函数将剩余的内容重新连接在一起。split

然后,我使用一个带有 while 循环的函数在设置该值之前处理键的数组。route

const data = [
  `name_1_2_1 Joseph Jones`,
  `name_1_2_2 Mary Poppins`,
  `name_1_2_3 Sebastian Quincy`,
  `age_1_2_1 20`,
  `age_1_2_2 40`,
  `age_1_2_3 60`,
];

const keyedData = data.map(line => {
  const bits = line.split(" ");
  
  const route = bits.shift(); // name_1_2_1

  const keyBits = route.split("_"); // [name, 1, 2, 1]
  const key = keyBits.shift(); // name
  
  return {
    route: keyBits,
    key,
    val: bits.join(' ') // the left over `Joseph Jones`
  }
})


function buildObject(data){
  const finalObject = {}
  
  data.forEach(item => {
    // Reset the target for this item to the `root` object
    let target = finalObject;
    while(item.route.length){
      let routeFragment = item.route.shift();
      // If the target doesn't have a property on this key, create one
      if(!target.hasOwnProperty(routeFragment)){
        target[routeFragment] = {};
      }
      // Now set the new target 
      target = target[routeFragment];
    }
    // Finally, update that value.
    target[item.key] = item.val;
  })
  
  return finalObject
}

const result = buildObject(keyedData);
console.log(result);

评论

0赞 Marcos Camargo 11/20/2023
当我查看由 keyedData 创建的对象时,作为数组的路由是空的。它按原样工作,但路由不应为空。这是我在控制台上看到的为什么它是空的?谢谢![{"route": [], "key": "age", "val": "40 anos"},
0赞 Djave 11/20/2023
控制台会在您查看该变量时显示该变量,而不是在控制台记录该变量时显示该变量。如果您将控制台 .log 更改为,您将在那一刻看到它。如果您对控制台的工作原理以及 javascript 如何引用基元以外的对象更感兴趣,您可以对此进行研究。console.log(JSON.stringify(keyedData));