Home > Software engineering >  JavaScript Algorithm For Continuous Filtering Data On Most Recent Results
JavaScript Algorithm For Continuous Filtering Data On Most Recent Results

Time:12-29

I need to write an algorithm where the user selects an option to filter a particular data and on every click it makes an api request returning the filtered data. As many times the user clicks it needs to continue to filter out the data. My question is, how can the algorithm save the most recent result and run a for/filter loop on the most recent results? Should I store the most recent results in localStorage in order to further filter the results? And when the user decides to unselect the data that they wanted to filter, it should show the user their previous results. The user should be able to continue to filter until they get the desired data. Please see example below.

***DATA***
let data = [
  {"id":0, "name":"John1", "age":29, "city":"seattle", "score": 95},
  {"id":1, "name":"John2", "age":28, "city":"seattle", "score": 95},
  {"id":2, "name":"John3", "age":29, "city":"seattle", "score": 85},
  {"id":3, "name":"John4", "age":30, "city":"austin", "score": 75},
  {"id":4, "name":"John5", "age":24, "city":"austin", "score": 85},
  {"id":5, "name":"John6", "age":30, "city":"aspen", "score": 84},
  {"id":6, "name":"John7", "age":31, "city":"aspen", "score": 100},
  {"id":7, "name":"John8", "age":31, "city":"aspen", "score": 93},
  {"id":8, "name":"John9", "age":35, "city":"denver", "score": 93},
  {"id":9, "name":"John10", "age":29, "city":"denver", "score": 75},
  {"id":10, "name":"John11", "age":28, "city":"denver", "score": 85},
  {"id":11, "name":"John12", "age":28, "city":"denver", "score": 85},
]
***FIRST USER SELECTED FILTER***
let firstFilter = [{"score":85}]

***FIRST FILTER RESULTS***
let firstFilterdResults = [
  {"id":2, "name":"John3", "age":29, "city":"seattle", "score": 85},
  {"id":4, "name":"John5", "age":24, "city":"austin", "score": 85},
  {"id":10, "name":"John11", "age":28, "city":"denver", "score": 85},
  {"id":11, "name":"John12", "age":28, "city":"denver", "score": 85},
 ]
***SECOND USER SELECTED FILTER***
let secondFilter = [{"age":28}]

***SECOND FILTER RESULTS***
let secondFilterdResults = [
  {"id":10, "name":"John11", "age":28, "city":"denver", "score": 85},
  {"id":11, "name":"John12", "age":28, "city":"denver", "score": 85},
 ]
***CURRENT ALGORITHM***

function filterDataList(data, firstFilter) {
  let firstFilteredResults = [];

  firstFilteredResults = data.filter((dataItem) => {
    var throwVar = 0 
    for (let item of firstFilter) {
      for (let key in item) {
        if (dataItem[key] === undefined || dataItem[key] !== item[key]) {
          throwVar = 0
        } else {
          return true
        }
      }



    }
    if (throwVar == 0) {
      return false
    }
  })

  return firstFilteredResults

}

CodePudding user response:

I think you should pass the filters as an array, not an object:

function filter(data, filters){
    let tmpData = data;
    let result;
    for(let filter of filters){
        result = [];
        for(let row of tmpData){
            switch(filter[0]){
                case 'id':
                    if(row.id   === filter[1]) result.push(row);
                    break;
                case 'name':
                    if(row.name === filter[1]) result.push(row);
                    break;
                case 'age':
                    if(row.age  === filter[1]) result.push(row);
                    break;
                case 'city':
                    if(row.city === filter[1]) result.push(row);
                    break;
                case 'score':
                    if(row.score=== filter[1]) result.push(row);
                    break;
            }
        }
        tmpData = result;
    }
    return result;
}


//test:
let data = [
  {"id":0, "name":"John1", "age":29, "city":"seattle", "score": 95},
  {"id":1, "name":"John2", "age":25, "city":"seattle", "score": 95},
  {"id":2, "name":"John3", "age":29, "city":"seattle", "score": 85},
  {"id":3, "name":"John4", "age":30, "city":"austin", "score": 75},
  {"id":4, "name":"John5", "age":24, "city":"austin", "score": 85},
  {"id":5, "name":"John6", "age":30, "city":"aspen", "score": 84},
  {"id":6, "name":"John7", "age":31, "city":"aspen", "score": 100},
  {"id":7, "name":"John8", "age":31, "city":"aspen", "score": 93},
  {"id":8, "name":"John9", "age":35, "city":"denver", "score": 93},
  {"id":9, "name":"John10", "age":29, "city":"denver", "score": 75},
  {"id":10, "name":"John11", "age":28, "city":"denver", "score": 85},
  {"id":11, "name":"John12", "age":28, "city":"denver", "score": 85}
];

let result = filter(data, [['age', 29], ['city', 'seattle']]);
console.log(result);

CodePudding user response:

The successive filter selections are really specifying a conjunction of keys and values...

age == x AND score == y AND ....

Just like an object!

Since users can presumably make these choices more than once, they might produce an errant filter like: age == x AND age == y.

Se we really want the query to be a conjunction of unique keys with values.

Just like an object!

// this expresses a conjunction of unique keys - values
let query = {}

let data = [...]
let filteredData = []

// add a key-value, pair and update the filtered data
function addFilter(key, value) {
  query[key] = value;

  const keys = Object.keys(query);
  filteredData = data.filter(datum => {
    return keys.every(key => datum[key] === query[key])
  });
}

function reset() {
  query = {}
}

CodePudding user response:

You can iterate the array and check if each object satisfies the passed filters. This works with filters having multiple elements and each element having multiple properties.

let data = [
  { id: 0, name: 'John1', age: 29, city: 'seattle', score: 95 },
  { id: 1, name: 'John2', age: 25, city: 'seattle', score: 95 },
  { id: 2, name: 'John3', age: 29, city: 'seattle', score: 85 },
  { id: 3, name: 'John4', age: 30, city: 'austin', score: 75 },
  { id: 4, name: 'John5', age: 24, city: 'austin', score: 85 },
  { id: 5, name: 'John6', age: 30, city: 'aspen', score: 84 },
  { id: 6, name: 'John7', age: 31, city: 'aspen', score: 100 },
  { id: 7, name: 'John8', age: 31, city: 'aspen', score: 93 },
  { id: 8, name: 'John9', age: 35, city: 'denver', score: 93 },
  { id: 9, name: 'John10', age: 29, city: 'denver', score: 75 },
  { id: 10, name: 'John11', age: 28, city: 'denver', score: 85 },
  { id: 11, name: 'John12', age: 28, city: 'denver', score: 85 },
];
let filters = [{ score: 85 }, { age: 28, city: 'denver' }];
const filterArr = (array, filters) =>
  array.filter((o) =>
    filters.every((f) => Object.entries(f).every(([k, v]) => o[k] === v))
  );
console.log(filterArr(data, filters));

You can also call filterArr as many times as you want.

let data = [
  { id: 0, name: 'John1', age: 29, city: 'seattle', score: 95 },
  { id: 1, name: 'John2', age: 25, city: 'seattle', score: 95 },
  { id: 2, name: 'John3', age: 29, city: 'seattle', score: 85 },
  { id: 3, name: 'John4', age: 30, city: 'austin', score: 75 },
  { id: 4, name: 'John5', age: 24, city: 'austin', score: 85 },
  { id: 5, name: 'John6', age: 30, city: 'aspen', score: 84 },
  { id: 6, name: 'John7', age: 31, city: 'aspen', score: 100 },
  { id: 7, name: 'John8', age: 31, city: 'aspen', score: 93 },
  { id: 8, name: 'John9', age: 35, city: 'denver', score: 93 },
  { id: 9, name: 'John10', age: 29, city: 'denver', score: 75 },
  { id: 10, name: 'John11', age: 28, city: 'denver', score: 85 },
  { id: 11, name: 'John12', age: 28, city: 'denver', score: 85 },
];
const filterArr = (array, filters) =>
      array.filter((o) =>
        filters.every((f) => Object.entries(f).every(([k, v]) => o[k] === v))
      );
let firstFilter = [{"score":85}]
let filteredArr = filterArr(data, firstFilter);
let secondFilter = [{"age":28}]
filteredArr = filterArr(filteredArr, secondFilter)
console.log(filteredArr)

  • Related