js陣列Array根據動態條件過濾
阿新 • • 發佈:2020-08-17
資料
[{ "name": "張三", "score": 153 }, { "name": "李四", "score": 206 }, { "name": "王五", "score": 68.5 }, { "name": "王六", "score": 83.5 }]
需求:需要根據動態的條件來對資料進行查詢。
步驟1:定義過濾器並初始化,比如我們要查詢王五以6分開頭的資料,條件定義:`姓名 equal 王五 && 成績 beginWith 6`
/// 過濾器集合,格式:{field:'',relationType:'',value: ''}/// field - 用於過濾的屬性(欄位) /// relationType - 關聯關係(比較方式),可選值有equal(等於)、notEqual(不等於)、like(模糊匹配)、beginWith(以它開頭)、endWith(以它結尾) /// value - 用於被比較的過濾器值 const filters = [] filters.push({ field: 'name', relationType: 'equal', value: '王五' }) filters.push({ field: 'score', relationType: 'beginWith', value:'6' })
步驟2:定義一個通用的過濾函式,過濾函式傳遞2個引數,第1個是需要被過濾的資料來源,第2個是過濾器集合,函式返回值是過濾後的資料來源
// 過濾資料來源 function filteringDataSources (source, filters) { // 動態表示式集合,用於儲存判斷某個物件是否滿足條件的函式 const expressions = [] // 遍歷過濾器集合,動態新增表示式函式 filters.forEach(item => { // 新增表示式函式,引數為陣列的每個資料物件 expressions.push((obj) => {// 是否符合條件 let isFit = false // 資料物件對應的屬性值 let objValue = '' // 用於被比較的過濾器值 const compareValue = item.value // 判斷資料物件是否存在用於過濾的屬性,如果不存在直接判定為不符合條件 if (typeof (obj[item.field]) === 'undefined') { isFit = false return isFit } // 獲取資料物件用於比較的屬性值,統一轉為字串型別,便於比較 objValue = String(obj[item.field]) // 判斷邏輯 if (item.relationType === 'equal') { // 等於 isFit = objValue === compareValue } else if (item.relationType === 'notEqual') { // 不等於 isFit = objValue !== compareValue } else if (item.relationType === 'like') { // 模糊匹配 isFit = objValue.includes(compareValue) } else if (item.relationType === 'beginWith') { // 以它開頭 isFit = objValue.startsWith(compareValue) } else if (item.relationType === 'endWith') { // 以它結尾 isFit = objValue.endsWith(compareValue) } // 返回當前表示式是否符合條件 return isFit }) }) // 遍歷資料來源 source = source.filter((item, index) => { // 是否符合條件 let isFit = true // 遍歷表示式集合,迴圈判斷每個用於過濾的表示式函式是否符合 for (let index = 0; index < expressions.length; index++) { // 獲取表示式函式 const expression = expressions[index] // 呼叫表示式函式,獲取結果 const result = expression(item) // 如果結果為false,則終止表示式集合的遍歷(即有一個條件不符合,則該條資料則被判定不滿足條件) if (!result) { isFit = false break } } // 返回當前資料物件是否符合條件,不符合條件則被過濾掉,不會出現在最終資料中 return isFit }) // 返回過濾後的資料來源 return source }
步驟3:呼叫過濾函式得到結果
if (filters.length > 0) { source = filteringDataSources(source, filters) }
結果:
Array(1) 0: {name(test_scores): "王五", score(test_scores): 68.5} length: 1
完整程式碼:
// 過濾資料來源 function filteringDataSources (source, filters) { // 動態表示式集合,用於儲存判斷某個物件是否滿足條件的函式 const expressions = [] // 遍歷過濾器集合,動態新增表示式函式 filters.forEach(item => { // 新增表示式函式,引數為陣列的每個資料物件 expressions.push((obj) => { // 是否符合條件 let isFit = false // 資料物件對應的屬性值 let objValue = '' // 用於被比較的過濾器值 const compareValue = item.value // 判斷資料物件是否存在用於過濾的屬性,如果不存在直接判定為不符合條件 if (typeof (obj[item.field]) === 'undefined') { isFit = false return isFit } // 獲取資料物件用於比較的屬性值,統一轉為字串型別,便於比較 objValue = String(obj[item.field]) // 判斷邏輯 if (item.relationType === 'equal') { // 等於 isFit = objValue === compareValue } else if (item.relationType === 'notEqual') { // 不等於 isFit = objValue !== compareValue } else if (item.relationType === 'like') { // 模糊匹配 isFit = objValue.includes(compareValue) } else if (item.relationType === 'beginWith') { // 以它開頭 isFit = objValue.startsWith(compareValue) } else if (item.relationType === 'endWith') { // 以它結尾 isFit = objValue.endsWith(compareValue) } // 返回當前表示式是否符合條件 return isFit }) }) // 遍歷資料來源 source = source.filter((item, index) => { // 是否符合條件 let isFit = true // 遍歷表示式集合,迴圈判斷每個用於過濾的表示式函式是否符合 for (let index = 0; index < expressions.length; index++) { // 獲取表示式函式 const expression = expressions[index] // 呼叫表示式函式,獲取結果 const result = expression(item) // 如果結果為false,則終止表示式集合的遍歷(即有一個條件不符合,則該條資料則被判定不滿足條件) if (!result) { isFit = false break } } // 返回當前資料物件是否符合條件,不符合條件則被過濾掉,不會出現在最終資料中 return isFit }) // 返回過濾後的資料來源 return source } let source = [{ 'name': '張三', 'score': 153 }, { 'name': '李四', 'score': 206 }, { 'name': '王五', 'score': 68.5 }, { 'name': '王六', 'score': 83.5 }] /// 過濾器集合,格式:{field:'',relationType:'',value: ''} /// field - 用於過濾的屬性(欄位) /// relationType - 關聯關係(比較方式),可選值有equal(等於)、notEqual(不等於)、like(模糊匹配)、beginWith(以它開頭)、endWith(以它結尾) /// value - 用於被比較的過濾器值 const filters = [] filters.push({ field: 'name', relationType: 'equal', value: '王五' }) filters.push({ field: 'score', relationType: 'beginWith', value: '6' }) source = filteringDataSources(source, filters) console.log(source)