Javascript将数组转换为对象数组

Posted

技术标签:

【中文标题】Javascript将数组转换为对象数组【英文标题】:Javascript Convert array to Array of Objects 【发布时间】:2021-01-07 17:04:51 【问题描述】:

我有一个表单,我正在使用 Ajax 向 API 提交数据。该表单包含一个重复器,可帮助用户重复输入任意数量的数据。用户在几个步骤后提交表单。当我尝试将值绑定到 Object 时未绑定。 API 是使用 Spring Boot 构建的,默认情况下,Jackson 用于将 JSON 转换为 Objects。

这是完整的代码,

f.submit(function(e)
            e.preventDefault();
            var ignoreFields = ["_csrf"];
            var unindexed_array = $(this).serializeArray().filter(val => ignoreFields.indexOf(val.name) === -1);
            var indexed_array = ;
            $.map(unindexed_array, function(n, i)
                indexed_array[n['name']] = n['value'];
            );
            $.ajax(
                  type: $(this).attr('method'), 
                  contentType: 'application/json',
                  url: $(this).attr('action'), 
                  data: JSON.stringify(indexed_array),
                  dataType: 'json', cache: false, timeout: 600000,
                  success: function (d) 
                  , error: function (e) 
                  
              );
        )

在 JSON.stringify() 之前

   
    act1[0].quantity: "4",
    act1[0].name: "abc",
    act1[0].status: "Working",
    act2[0].quantity: "5",
    act2[0].id: "1",
    act3[0].quantity: "4",
    act3[0].id: "2",
    act3[0].unit: "mm",
    activity: "zdzdsd zsdsad",
    endTime: "23:02",
    location: "sdasd",
    note: "sdfsdfsd sdfsdfsd",
    startTime: "03:03"
  

如果我将上述代码转换为以下格式,我希望它可以工作,因为我使用的是列表,杰克逊图书馆将能够识别这种格式

    
    endTime: "23:02",
    location: "sdasd",
    note: "sdfsdfsd sdfsdfsd",
    startTime: "03:03",
    act1:[
       quantity: "4",
       name: "abc",
       status: "Working"
    ],
    act2:[
       quantity: "5"
       id: "1"
    ],
    act3:[
       quantity: "4"
       id: "2",
       unit: "mm"
    ]

我在javascript中尝试了很多方法来转换成这种格式,我们如何才能实现上述格式?

【问题讨论】:

您在这里尝试做什么有点不清楚。我不确定你的输入是什么,你的输出是什么。并且这两个样本都不是对象的合法 JS 表示(尽管后者如果包裹在 - 中。你想将什么转换成什么?你能告诉我们一些你尝试过的东西吗? @ScottSauyet我修改了我的问题,不知道你能不能看懂,我真的不知道怎么问这个,是格式问题,你看到的就是我需要的格式第一个是我拥有的格式。如何将第一个 JSON 转换为最后一个 JSON 格式? 您如何获得该输入?它是如图所示的多行字符串吗?因为它仍然不是合法的 JS 格式。对象键可以包含任何字符,但在源代码或 JSON 中,不允许使用除字母数字字符 /$ /_ 之外的任何字符,除非包装在字符串中。也就是说,这是不合法的:act1[0].quantity: "4",但是这(将密钥包裹在字符串中)是合法的:"act1[0].quantity": "4" 【参考方案1】:

保留有用函数的个人库通常可以使这种转换更容易。我已经多次使用包含的assocPathhydrate 之类的函数,包括recent SO answer(其中包含有关它们的功能的更多详细信息。)

将我的解决方案放在一起涉及一些相当小的功能。我确实必须假设您的输入结构从问题中并不完全清楚,即显示的内容是真实 JS 格式的某种速记。如果没有,大部分代码可能仍然可以工作;只是可能需要一些额外的努力才能转换成可用的东西。

这就是它的样子:

// utility functions
const assoc = (prop, val, obj) => 
  Number .isInteger (prop) && Array .isArray (obj)
    ? [... obj .slice (0, prop), val, ...obj .slice (prop + 1)]
    : ...obj, [prop]: val

const assocPath = ([p = undefined, ...ps], val, obj) => 
  p == undefined
    ? obj
    : ps.length == 0
      ? assoc(p, val, obj)
      : assoc(p, assocPath(ps, val, obj[p] || (obj[p] = Number .isInteger (ps[0]) ? [] : )), obj)

const hydrate = (pvEntries) =>
  pvEntries .reduce ((a, [k, v]) => assocPath (k, v, a), )


// helper functions
const extractIndices = s => 
  s .split (/[\[\]]/)
    .map (s => /^\d+$/ .test (s) ? Number(s) : s)
    .filter(n => n !== '')

const makePath = (s) => 
  s .split ('.') .flatMap (extractIndices)


// main function
const transform = (input) =>
  hydrate (
    Object .entries (input)
      .map (([k, v]) => [makePath (k), v])
  )


// test data
const input = "act1[0].quantity": "4", "act1[0].name": "abc", "act1[0].status": "Working", "act2[0].quantity": "5", "act2[0].id": "1", "act3[0].quantity": "4", "act3[0].id": "2", "act3[0].unit": "mm", "activity": "zdzdsd zsdsad", "endTime": "23:02", "location": "sdasd", "note": "sdfsdfsd sdfsdfsd", "startTime": "03:03"


// demo
console .log (transform (input))
.as-console-wrapper max-height: 100% !important; top: 0

使用我已经拥有的助手,为了构建它,我唯一需要的技巧就是编写一些代码来将这种样式输入:"act1[0].quantity" 转换为我更喜欢使用的样式,["act1", 0, "quantity"]。该代码是makePath,它取决于extractIndices。虽然它们可以在这里轻松组合,但 extractIndices 看起来好像单独使用它可能有用。

使用它,我们可以将您上面的输入转换为:

[
  [["act1", 0, "quantity"], "4"],
  [["act1", 0, "name"], "abc"],
  [["act1", 0, "status"], "Working"],
  [["act2", 0, "quantity"], "5"],
  [["act2", 0, "id"], "1"],
  [["act3", 0, "quantity"], "4"],
  [["act3", 0, "id"], "2"],
  [["act3", 0, "unit"], "mm"],
  [["activity"], "zdzdsd zsdsad"],
  [["endTime"], "23:02"],
  [["location"], "sdasd"],
  [["note"], "sdfsdfsd sdfsdfsd"],
  [["startTime"], "03:03"]
]

然后在该结果上简单地调用hydrate

【讨论】:

你拯救了我的一天。非常感谢。 @SebrinThomas:我很高兴它有帮助,但我希望你带走的不仅仅是代码。更重要的是构建和重用许多简单函数以构建更复杂的函数的概念。

以上是关于Javascript将数组转换为对象数组的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript:将数组转换为对象

Javascript将数组转换为对象数组

将数组的数组转换为javascript中的对象

我想用 JavaScript 将对象数组转换为对象 [重复]

Javascript:将数组转换为对象的最佳方法是啥? [复制]

对象值的Javascript数组转换为多维数组