首页 > 解决方案 > 在对象数组中提取具有相同键的非重复值

问题描述

我在 Vue 应用程序中得到了一些产品的 API 响应:

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

我在选择具有相同键的非重复值时遇到问题。我的意思是,我想为每个产品和每个属性产品提取尺寸、颜色和性别的不同值,因为它们放在一个<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>

任何形式的帮助将不胜感激。非常感谢您的宝贵时间!

标签: javascriptvue.js

解决方案


如果我正确理解您的问题,您可以使用 Lodash 的uniqBy方法轻松获取每个属性的唯一值列表:

    <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 && comb.sex === sex && comb.size === size;
        });
        return combination.price;
    }

推荐阅读