Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
189 views
in Technique[技术] by (71.8m points)

Javascript Convert array to Array of Objects

I have a form and I am using Ajax to submit data to the API. The form contains a repeater which aids the user to enter any number of data repeatedly. The user submits the form after a few steps. When I try to bind the value to the Object is not binding. The API is built using Spring Boot, and by default, Jackson is used for conversion of JSON to Objects.

Here is the full code,

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) {
                  }
              });
        })

before 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"
  }

if I convert the above code to the following format I expect this to work, since I am using a list and Jackson Library will be able to identify this format

    {
    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"
    }]
}

I tried many ways in Javascript to convert into this format, How can we achieve the above format?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Keeping a personal library of helpful functions can often make this sort of transformation easier. I have used functions like the included assocPath, and hydrate many times, including in a recent SO answer (which has more details about what they do.)

Put together my solution involves a number of fairly small functions. I do have to make an assumption about your input structure not entirely clear from the question, namely that what's displayed is some kind of shorthand for a real JS format. If not, most of the code will probably still work; it just might take some additional effort to convert to something usable.

This is what it looks like:

// 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}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...