Josh
Josh

Reputation: 384

Dynamically create object with jQuery

I want to dynamically create an array of objects.

The array will be called 'groups'. It will contain an unknown number of objects (these are the Group Names) which will be determined by the ID of an element. Each object will contain an unknown number of properties (these are the Group Properties), these will be determined by the inner text of a div and their value will be determined by the inner text of another div.

I know how to get each of these values using .each() and .attr('ID') and .text(). I just can't work out how to create the array of objects.

// Example HTML 
<div id="england">
    <div class="property">health</div>
    <div class="count">3</div>
    <div class="property">education</div>
    <div class="count">1</div>
    <div class="property">entertainment</div>
    <div class="count">12</div>
</div>
<div id="scotland">
    <div class="property">geography</div>
    <div class="count">5</div>
    <div class="property">history</div>
    <div class="count">2</div>
</div>
<div id="wales">
    <div class="property">illustration</div>
    <div class="count">4</div>
    <div class="property">business</div>
    <div class="count">6</div>
    <div class="property">fashion</div>
    <div class="count">3</div>
</div>

.

// Example JSON output of the 'groups' array
{  
    "england":{  
        "health":"3",
        "education":"1",
        "entertainment":"12"
    },
    "scotland":{  
        "geography":"5",
        "history":"2"
    },
    "wales":{  
        "illustration":"4",
        "business":"6",
        "fashion":"3"
    }

}

Upvotes: -1

Views: 564

Answers (1)

Nenad Vracar
Nenad Vracar

Reputation: 122047

You can do this with reduce() to return object and Array.from to turn jQuery objects to array of objects so you can use reduce method on it.

// Select direct div children of body, make an array from them and use reduce on it
const data = Array.from($('body > div')).reduce(function(r, e) {
  // Add property for each div / object in array where key is id and value will be another object from array of children of current div 
  r.groups[e.id] = Array.from($(e).children())
    .reduce(function(acc, el, i, arr) {
      // Here we are looping each element in div and if (i % 2 == 0) that means its property so we will use it for key and the next one will be used for value
      if (i % 2 == 0) acc[el.textContent] = arr[i + 1].textContent
      // return accumulator
      return acc
    }, {})
  // return accumulator
  return r;
  // Accumulator of first reduce is object with groups property
}, {groups: {}})

console.log(data)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="england">
  <div class="property">health</div>
  <div class="count">3</div>
  <div class="property">education</div>
  <div class="count">1</div>
  <div class="property">entertainment</div>
  <div class="count">12</div>
</div>
<div id="scotland">
  <div class="property">geography</div>
  <div class="count">5</div>
  <div class="property">history</div>
  <div class="count">2</div>
</div>
<div id="wales">
  <div class="property">illustration</div>
  <div class="count">4</div>
  <div class="property">business</div>
  <div class="count">6</div>
  <div class="property">fashion</div>
  <div class="count">3</div>
</div>

Upvotes: 0

Related Questions