Извлечение неповторяющихся значений с одним и тем же ключом в массив объектов

#javascript #vue.js

#javascript #vue.js

Вопрос:

Я получил этот ответ API для некоторых продуктов в приложении Vue:

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

У меня проблема с выбором неповторяющихся значений с одним и тем же ключом.
Я имею в виду, я хочу извлечь для каждого продукта и каждого атрибута product разные значения размера, цвета и пола, чтобы поместить их в <select> . Затем мне нужно будет динамически получать согласованную «цену» в зависимости от выбора пользователя по полу, цвету и размеру.

Я застрял на этом этапе прямо сейчас (сокращенный код):

 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>  

Любая помощь будет оценена. Большое спасибо за ваше время!

Комментарии:

1. Мне не совсем понятно, чего вы хотите. Вам нужно одно поле выбора или три поля выбора?

2. @TKoL Я хочу по одному выбору для каждого атрибутивного продукта. Идея состоит в том, чтобы отображать их динамически в зависимости от API ответа на данные. В этом случае для получения цены есть три атрибута.

Ответ №1:

Если я правильно понимаю вашу проблему, вы могли бы использовать uniqBy метод Lodash, чтобы легко получить список уникальных значений для каждого атрибута:

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

Затем, когда у вас есть выбранные значения, вы можете найти цену примерно так:

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