Сравнение двух массивов vue

В компоненте есть два массива:

Первый (region):

[
   { name: "Москва" },
   { name: "Екатеринбург" }
]

Второй (deliveryTime):

[
  { name: "Екатеринбург", delivery_time: "2-7" },
  { name: "Москва", delivery_time: "1-3"}
]

Если из первого массива выбран, скажем, город Москва, нужно подставлять время доставки (в данном случае 1-3).

Что получилось сделать:

<div v-for="(reg, index) in deliveryTime" :key="index"> 
   <span :class="{"reg": findTime(reg)}"> {{ reg.delivery_time }} -- {{ reg.name }} </span>
</div>

methods: {
  findTime(reg) {
    return this.region.includes(reg);
  }
}

Нужно оставить только время доставки и название города (скриншот: Екатерибург, время доставки: 5-8). Как можно улучшить/переписать код, дабы добиться того, что требуется?

введите сюда описание изображения


Ответы (1 шт):

Автор решения: yar85

Задача до конца не ясна... но класс таких задач (предполагающих "v-for по части элементов коллекции") в Vue решается через вычисляемое свойство:

<div v-for="dt in selectedRegionsDeliveryTime" :key="dt.name"> 
  <span>{{ dt.delivery_time }} -- {{ dt.name }}</span>
</div>

computed: {
  selectedRegions() {
    return this.region.reduce((rslt, { name }) => rslt.add(name), new Set());
  },
  selectedRegionsDeliveryTime() {
    return this.deliveryTime.filter(dt => this.selectedRegions.has(dt.name));
  },
},

Тут выводятся все элементы deliveryTime у которых значение name совпадает со значением name одного из элементов region.

Вспомогательное свойство selectedRegions введено только для того чтобы на каждой итерации filter повторно не перебирать весь массив region (в котором мешается еще и совершенно бесполезная обертка каждого значения в объект).
Ключом v-for лучше брать свойство перебираемых в этом цикле объектов, с уникальным значением (использование индекса элемента коллекции в качестве ключа - плохая практика).


Если же нужен только один элемент массива deliveryTime, то все еще проще - т.к. значение для его поиска уже есть (предполагается) в компоненте, и остается добавить к нему только вычисляемое свойство возвращающее результат find:

<div v-if="Boolean(selectedRegion)">
  <span>{{ curDeliveryTime.delivery_time }} -- {{ curDeliveryTime.name }}</span>
</div>

data() { return {
  selectedRegion: null,    // "выбранный" в UI регион (присваивать элемент массива `region`)
  /* .... */
}},
computed: {
  curDeliveryTime() {
    return this.deliveryTime.find(dt => dt.name === this.selectedRegion.name);
  },
},
→ Ссылка