Alberto Rhuertas
Alberto Rhuertas

Reputation: 773

Extract non-repeated values with the same key in array of objects

I got this API response of some products in a Vue app:

products = [{
    "id": 4,
    "name": "producto02",
    "image": "https://example.com/images/example.png",
    "combinactions": [{
        "id": 1,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "color": "blanco",
        "sex": "masculino",
        "size": "42"
    }, {
        "id": 2,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "color": "blanco",
        "sex": "masculino",
        "size": "39"
    }, {
        "id": 3,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "color": "blanco",
        "sex": "masculino",
        "size": "39"
    }, ]
}, {
    "id": 5,
    "name": "producto",
    "image": "https://api.pre.runrunsports.com/api/imagees_productos/figura1_8.png",
    "combinactions": [{
        "id": 33,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "masculino",
        "color": "blanco"
    }, {
        "id": 34,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "masculino",
        "color": "azul"
    }, {
        "id": 35,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "masculino",
        "color": "negro"
    }, {
        "id": 36,
        "price": "10.00",
        "price_antes": "10.00",
        "stock": 0,
        "size": "41",
        "sex": "masculino",
        "color": "rojo"
    }]
}]

I'm having a problem with selecting non-repeated values with the same key. I mean, I want to extract for each product and each attribute product the different values of size, color and sex due to put them in a <select>. Then, I will need to get the matched "price" dynamically depending on the user selection by sex, color and size.

I'm stuck at this point right now (reduced code):

new Vue({
  el: '#list-example',
  data: {
    products: [{
      id: 4,
      name: "producto02",
      image: "https://example.com/images/example.png",
      atributes: {
        "color": "Color",
        "sex": "Sex",
        "size": "Size"
      },
      combinations: [{
          id: 1,
          price: "10.00",
          price_antes: "10.00",
          stock: 0,
          color: "blanco",
          sex: "masculino",
          size: "42"
        },
        {
          id: 2,
          price: "10.00",
          price_antes: "10.00",
          stock: 0,
          color: "blanco",
          sex: "masculino",
          size: "39"
        }, {
          id: 3,
          price: "10.00",
          price_antes: "10.00",
          stock: 0,
          color: "blanco",
          sex: "masculino",
          size: "39"
        }
      ]
    }, {
      id: 5,
      name: "producto",
      image: "https://example.com/images/example.png",
      atributes: {
        "color": "Color",
        "sex": "Sex",
        "size": "Size"
      },
      combinations: [{
        id: 33,
        price: "10.00",
        price_antes: "10.00",
        stock: 0,
        size: "41",
        sex: "masculino",
        color: "blanco"
      }, {
        id: 34,
        price: "10.00",
        price_antes: "10.00",
        stock: 0,
        size: "41",
        sex: "masculino",
        color: "azul"
      }, {
        id: 35,
        price: "10.00",
        price_antes: "10.00",
        stock: 0,
        size: "41",
        sex: "masculino",
        color: "negro"
      }]
    }],
  },
  methods: {

  }
})
ul {
  list-style: none;
}

span.title {
  font-size: 20px;
  margin-bottom: 20px;
}

.price {
  font-size: 30px;
  color: red;
}

select {
  max-width: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="list-example">
  <ul>
    <li v-for="(product, index) in products" v-bind:key="product.id">
      <span class="title">{{product.name}}</span>
      <div class="form-group valid col-12 field-select" v-for="(atribute, index) in product.atributes" :key="`atribute-${index}`">
        <label v-bind:for="index + product.id"><span>Select {{ atribute }}</span>
                    </label>
        <div class="field-wrap">
          <select v-bind:id="index + product.id" class="form-control">
            <option v-for="combination in product.combinations" :key="combination.id">
              {{ combination }}
            </option>
          </select>
        </div>
      </div>

      <span class="price">
      50€ 
    </span>
      <p>(get the price dynamically depending on user selection)</p>
    </li>
  </ul>
</div>

Any kind of help would be appreciated. Many thanks for your time!

Upvotes: 0

Views: 54

Answers (1)

Hannah
Hannah

Reputation: 1143

If I understand your problem correctly, you could use Lodash's uniqBy method to easily get a list of unique values for each attribute:

    <select v-for="(val, attribute) in product.attributes" class="form-control">
        <option v-for="combination in uniqueValsForAttr(product.combinations, attribute)">
            {{ combination }}
        </option>
    </select>

    ...

    methods: {
        uniqueValsForAttr(combinations, attr) {
            return _.uniqBy(combinations, attr).map(item => item[attr]);
        }
    }

Then, when you have your selected values, you can find the price with something like this:

    getPrice(product, selections) {
        const { color, sex, size } = selections;
        const combination = product.combinations.find(comb => {
            return comb.color === color && comb.sex === sex && comb.size === size;
        });
        return combination.price;
    }

Upvotes: 1

Related Questions