簡體   English   中英

如何從 javascript 中的多個屬性中過濾數組的 JSON 對象

[英]How to filter JSON objects of array from multiple attributes in javascript

我目前正在努力使用一個小型 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中的這些變量的名稱與您的船只中的變量相匹配,例如, brand而不是brands

我會將年份設為范圍值(最小值-最大值)而不是數組。 由你決定。

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

抱歉,我無法測試代碼。 但我希望你明白這一點!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM