Mik_A Mik_A - 3 years ago 138
Javascript Question

Get highest values from objects created with map

I have dynamically added divs with nested divs to the dom. These have data-attributes:

data-name-nr
,
data-model
,
data-price
.

What I want is to take the highest value of "data-price" to an array from each of all "data-div". In my example there is two nested divs inside the last

More explanation: In my example I have three div with class "frame" = I need an array with three values. In reality there night be whatever between 1 and 10 or even more.

So the outcome of my example would be

let array = [100,150,200]
or
let object = {1:100,2:150,3:200} //from the name-nr


So far I only managed to map the
data-item
s
I tried with
map.get
and other, they all gave me errors and I don't know which direction I should go. Please can you help?

Example:

HTML

<div class="flex">
<div class="frame" data-name-nr="1">
<div class="border" data-name-nr="1" data-price="100" data-div="1/1"></div>
</div>
<div class="frame" data-name-nr="2">
<div class="border" data-name-nr="2" data-price="150" data-div="1/1"></div>
</div>
<div class="frame" data-name-nr="3">
<div class="border fifty" data-name-nr="3" data-price="100" data-div="1/2"></div>
<div class="border fifty" data-name-nr="3" data-price="200" data-div="2/2"></div>
</div>
</div>


JS

function functionName() {
jQuery( ".frame .box" ).map(function() {

const key = ['name','model','price']
let values = [[jQuery(this).data("name-nr"),( jQuery(this).data('div')),( jQuery(this).data('price'))]]
let result = values.map(row =>
row.reduce((acc, cur, i) =>
(acc[key[i]] = cur, acc), {}))
console.log(result[0])
})
}

$(document).on('click', '.click', functionName)


Console

Object { name: 1, model: "1/1", price: 100 }
Object { name: 2, model: "1/1", price: 150 }
Object { name: 3, model: "1/2", price: 100 }
Object { name: 3, model: "2/2", price: 200 }


https://jsfiddle.net/mik_a/a6jt7kb0/

Answer Source

Create a hash table by reducing to a hash with unique names with the largest price and then take them out to the array as required.

See demo below:

function functionName() {
  let hash = jQuery(".frame .box").map(function() {
    return {
      name: jQuery(this).data("name-nr"),
      model: jQuery(this).data('div'),
      price: jQuery(this).data('price')
    };
  }).get().reduce(function(p,c){
      if((p[c.name] && p[c.name].price < c.price) || !p[c.name])
        p[c.name] = c
      return p;
  },Object.create(null));
  let result = Object.keys(hash).map(function(e) {
     return hash[e];
  });
  console.log(result);
}

$(document).on('click', '.click', functionName)
.flex {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 400px;
  height: 300px;
}

.frame {
  outline: 1px solid red;
  flex: 1;
  display: flex;
  flex-direction: column;
  height: 100%;
}

.box {
  border-top: 1px solid green;
}

.fifty {
  height: 50%;
}

button {
  width: 100px;
  height: 35px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex">
  <div class="frame" data-name-nr="1">
    <div class="box" data-name-nr="1" data-price="100" data-div="1/1"></div>
  </div>
  <div class="frame" data-name-nr="2">
    <div class="box" data-name-nr="2" data-price="150" data-div="1/1"></div>
  </div>
  <div class="frame" data-name-nr="3">
    <div class="box fifty" data-name-nr="3" data-price="100" data-div="1/2"></div>
    <div class="box fifty" data-name-nr="3" data-price="200" data-div="2/2"></div>
  </div>
</div>
<button class="click" value="CLICK">
click
</button>

and the ES6 version:

function functionName() {
  let hash = jQuery(".frame .box").map(function() {
    return {
      name: jQuery(this).data("name-nr"),
      model: jQuery(this).data('div'),
      price: jQuery(this).data('price')
    };
  }).get().reduce((p, c) => {
    if ((p[c.name] && p[c.name].price < c.price) || !p[c.name])
      p[c.name] = c;
    return p;
  }, Object.create(null));
  let result = Object.keys(hash).map(e => hash[e]);
  let sum = Object.keys(hash).map(e => hash[e].price).reduce((p,c) => p + c, 0);
  console.log(result, sum);
}

$(document).on('click', '.click', functionName)
.flex{display:flex;align-items:center;justify-content:center;width:400px;height:300px}.frame{outline:1px solid red;flex:1;display:flex;flex-direction:column;height:100%}.box{border-top:1px solid green}.fifty{height:50%}button{width:100px;height:35px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex">
  <div class="frame" data-name-nr="1">
    <div class="box" data-name-nr="1" data-price="100" data-div="1/1"></div>
  </div>
  <div class="frame" data-name-nr="2">
    <div class="box" data-name-nr="2" data-price="150" data-div="1/1"></div>
  </div>
  <div class="frame" data-name-nr="3">
    <div class="box fifty" data-name-nr="3" data-price="100" data-div="1/2"></div>
    <div class="box fifty" data-name-nr="3" data-price="200" data-div="2/2"></div>
  </div>
</div>
<button class="click" value="CLICK">
click
</button>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download