gpt4 book ai didi

javascript - 如何在javascript中从多个属性中过滤数组的JSON对象

转载 作者:行者123 更新时间:2023-12-02 20:55:56 25 4
gpt4 key购买 nike

我目前正在努力开发一个小型 VueJS 应用程序,用于从基于下拉列表的多个值中过滤 API 响应。

如果一个过滤器是在 if (filtered) 外部声明的,而第二个条件是在内部声明的,那么我可以管理两个过滤器。

但是我想知道例如超过两个选项的情况如何。代码附在下面。

// Trunkera beskrivning
Vue.filter("truncate", function (value, limit) {
if (value.length > limit) {
value = value.substring(0, limit - 3) + "...";
}
return value;
});

new Vue({
el: "#app",
data: function () {
return {
visible: false,
boats: null,
filter: {
options: {
brands: [],
model: [],
engineBrands: [],
engineModels: [],
type: [],
maxPrice: null,
minPrice: null,
years: [],
}
},
selected: {
options: {
brand: null,
length: 1000,
condition: null,
engineBrand: null,
engineModel: null,
engineType: null,
fridge: null,
kitchen: null,
type: null,
shower: null,
year: null,
water: null,
wc: null
}
}
};
},
created() {
const vm = this;
fetch(
'https://www.sokbat.se/api/Ad?json=%7b"CompanyId":"5055","AdCategoryId":"10","SortOrder":0,"StartAd":0,"NumberOfAds":0%7d'
)
.then((response) => {
return response.json();
})
.then((data) => {
let arr = [];
// fyll på båtar
vm.boats = data;
// forEach...hämta detaljer
/*data.forEach((boat) => {
fetch(`https://www.sokbat.se/api/ad/${boat.AdId}`)
.then((response) => {
arr.push(response.json())
})
})*/
this.calcAttributes(data);
//vm.boats = arr;
});
},
computed: {
computed_items: function () {
const vm = this;
let filterType = this.selected.options.type,
filterEngineModel = this.selected.options.engineModel,
filterBrand = this.selected.options.brand,
// Ranges
filterPrice = this.selected.options.price,
filterYear = this.selected.options.year,
filterLength = this.selected.options.length,
filterWidth = this.selected.options.width;

return this.boats.filter(function (item) {
let filtered = true;

if (filtered) {
// Båttyp
if (filterType && filterType.length > 0) {
filtered = item.MotoBoatTypeSelectionCaption == filterType;
}
// Märke
if (filterBrand && filterBrand.length > 0) {
filtered = item.Brand == filterBrand;
}
// Båtmotor
if (filterEngineModel && filterEngineModel.length > 0) {
filtered = item.EngineModel == filterEngineModel;
}
// Motorår
if (filterYear && filterYear != "") {
filtered = item.BoatYear == filterYear;
}
/* Pris
if (filterPrice && filterPrice[0] > vm.filter.options.minPrice) {
filtered = item.Price >= filterPrice[0]
}
// Längd
if (filterWidth && filterWidth[0] >= vm.filter.options.minWidth) {
filtered = item.Width >= filterWidth[0]
}
if (filterLength && filterLength[0] >= vm.filter.options.minLength) {
filtered = item.Length >= filterLength[0]
}*/
}
return filtered;
});
}
},
mounted: function () {
const vm = this;
let i = 0;
this.$watch('selected', function () {
console.log(vm.computed_items);
}, {deep:true})
},
methods: {
calcAttributes(data) {
const vm = this;
let tmp_brands = [],
tmp_models = [],
tmp_yrs = [],
tmp_width = [],
tmp_types = [];

data.forEach((item) => {
tmp_brands.push(item.Brand);
tmp_models.push(item.EngineModel);
tmp_yrs.push(item.BoatYear);
tmp_types.push(item.MotoBoatTypeSelectionCaption)
});

let maxPrice = 0,
minPrice = 0,
minWidth = 0,
maxWidth = 0,
minLength = 0,
maxLength = 0;
data.forEach(item => {
if (item.Price >= maxPrice) {
maxPrice = item.Price
}
if (item.Price <= maxPrice) {
minPrice = item.Price
}
//
if (item.Width >= maxWidth) {
maxWidth = item.Width
}
if (item.Width <= minWidth) {
minWidth = item.Width
}
//
if (item.Length >= maxLength) {
maxLength = item.Length
}
if (item.Length <= minLength) {
minLength = item.Length
}
});
// min/max bredd
// unique's
vm.filter.options.maxPrice = maxPrice;
vm.filter.options.minPrice = minPrice;
//
vm.filter.options.maxWidth = maxWidth;
vm.filter.options.minWidth = minWidth;
vm.filter.options.type = Array.from(new Set(tmp_types));
//
vm.filter.options.maxLength = maxLength;
vm.filter.options.minLength = minLength;
vm.filter.options.brands = Array.from(new Set(tmp_brands))
vm.filter.options.engineModels = Array.from(new Set(tmp_models))
vm.filter.options.years = Array.from(new Set(tmp_yrs));
}
}
});
[v-cloak]{display:none}body{font-family:Ubuntu}.filter-box{background:#333;border-radius:5px;padding:1rem;margin:2rem}.results{padding:1rem;margin:2rem}.el-row{margin-bottom:20px}.el-row:last-child{margin-bottom:0}.el-col{border-radius:4px}.bg-purple-dark{background:#99a9bf}.bg-purple{background:#d3dce6}.bg-purple-light{background:#e5e9f2}.grid-content{border-radius:4px;min-height:36px}.row-bg{padding:10px 0;background-color:#f9fafc}.el-select{width:100%}.el-input__inner{color:#333!important}.inline>p{color:#fff;margin:0;padding:0}.boat-card{margin:10px}.time{font-size:16px;line-height:20px;color:#999}.time p{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.time p br{display:none}.bottom{margin-top:13px;line-height:12px}.button{padding:0;float:right}.image{width:100%;display:block}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}input::placeholder{color:#333!important}.el-col.el-col-8.el-col-xs-24.el-col-sm-12.el-col-md-8.el-col-lg-6{min-height:350px}.fade-enter-active,.fade-leave-active{transition:opacity .5s}.fade-enter,.fade-leave-to{opacity:0}a{text-decoration:none}
<div id="app" v-cloak>

<div class="filter-box">

<el-row :gutter="20">
<el-col :span="6">
<el-select v-model="selected.options.brand" placeholder="Märke">
<el-option default label="Alla" value=""></el-option>
<el-option v-for="item in filter.options.brands" :key="item" :label="item" :value="item">
</el-option>
</el-select>
</el-col>

<el-col :span="12">
<div class="inline">
<p>Pris</p>
<el-slider v-model="selected.options.price" range :min="filter.options.minPrice" :max="filter.options.maxPrice">
</el-slider>
</div>
</el-col>

<el-col :span="6">
<el-select v-model="selected.options.engineModel" placeholder="Motormodell">
<el-option default label="Alla" value=""></el-option>
<el-option v-for="item in filter.options.engineModels" :key="item" :label="item" :value="item">
</el-option>
</el-select>
</el-col>

</el-row>


<el-row :gutter="20">
<el-col :span="6">
<el-select v-model="selected.options.type" placeholder="Båttyp">
<el-option default label="Alla" value=""></el-option>
<el-option v-for="item in filter.options.type" :key="item" :label="item" :value="item">
</el-option>
</el-select>
</el-col>

<el-col :span="6">
<div class="inline">
<p>Bredd</p>
<el-slider v-model="selected.options.width" range :min="filter.options.minWidth" :max="filter.options.maxWidth">
</el-slider>
</div>
</el-col>

<el-col :span="6">
<div class="inline">
<p>Längd</p>
<el-slider v-model="selected.options.length" range show-stops :min="filter.options.minLength" :max="filter.options.maxLength">
</el-slider>
</div>
</el-col>

<el-col :span="6">
<el-select v-model="selected.options.year" placeholder="År">
<el-option default label="Alla" value=""></el-option>
<el-option v-for="item in filter.options.years" :key="item" :label="item" :value="item">
</el-option>
</el-select>
</el-col>

</el-row>

</div>

<div v-if="boats.length > 1" class="results">
<el-row>

<el-col v-for="(boat, i) in computed_items" :span="8" :key="i" :xs="8" :sm="8" :md="8" :lg="6">
<transition name="fade">
<a :href="`https://marine.local/bat/?id=${boat.AdId}`" target="_blank">
<el-card class="boat-card" :body-style="{ padding: '8px' }" shadow="hover">
<img :src=`${boat.AdResourceURI}` class="image">
<div style="padding: 14px;">
<span>{{boat.AdTitle}}</span>
<div class="bottom clearfix">
<time class="time" :inner-html.prop="boat.AdIntroduction | truncate(60)"></time>
<el-button type="text" class="button">
{{boat.Price.toLocaleString('sv-SE', { style: 'currency', currency: 'SEK' })}}
</el-button>
</div>
</div>
</el-card>
</a>
</transition>

</el-col>

</el-row>
</div>

</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" rel="stylesheet" />
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

最佳答案

您已经在 data.filter.options 中拥有过滤器。使用它们。您可能需要添加 minLengthmaxLength 等。

您还必须确保 this.filter.options 中这些变量的名称与您船上的变量匹配,例如品牌而不是品牌

我会将年份设置为范围值(最小值-最大值)而不是数组。由你决定。

computed: {
filtered_boats: function () {
let filtered = this.boats;

// the minimums
let mins = {
"minPrice": 'price',
"minLength": 'length',
...
};
filtered = Object.keys(mins).forEach(k => if (this.filter.options[k] !== null) filtered = filtered.filter(boat => boat[mins[k]] >= this.filter.options[k]));

// the maximums
let maxs = {
"maxPrice": 'price',
"maxLength": 'length',
...
};
filtered = Object.keys(maxs).forEach(k => if (this.filter.options[k] !== null) filtered = filtered.filter(boat => boat[maxs[k]] <= this.filter.options[k]));

// the multi-value filters
let fields = ['brand', 'model', 'type', ...];
filtered = fields.forEach(f => if (this.filter.options[f].length > 0) filtered = filtered.filter(boat => this.filter.options[f].indexOf(boat[f]) != -1));

return filtered;
}
}

抱歉,我无法测试代码。但我希望你能明白!

关于javascript - 如何在javascript中从多个属性中过滤数组的JSON对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61485210/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com