【问题标题】:JavaScript Algorithm For Continuous Filtering Data On Most Recent Results用于在最近结果上连续过滤数据的 JavaScript 算法
【发布时间】:2021-12-28 15:54:22
【问题描述】:

我需要编写一个算法,让用户选择一个选项来过滤特定数据,并在每次点击时发出一个返回过滤数据的 api 请求。用户点击的次数越多,它就需要继续过滤掉数据。我的问题是,算法如何保存最新结果并在最新结果上运行 for/filter 循环?我应该将最新结果存储在 localStorage 中以便进一步过滤结果吗?当用户决定取消选择他们想要过滤的数据时,它应该向用户显示他们之前的结果。用户应该能够继续过滤,直到他们获得所需的数据。请参阅下面的示例。

***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

}

【问题讨论】:

  • 每个过滤器是否总是有一个对象包含一个属性?
  • 实际上是的,因为每次点击它都会向服务器发送一个带有一个键/值对的对象。每次点击都会发出一个 api 请求。

标签: javascript algorithm


【解决方案1】:

连续的过滤器选择实际上是指定键和值的结合...

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

就像一个物体!

由于用户可能会多次做出这些选择,因此他们可能会产生错误的过滤器,例如:age == x AND age == y

我们真的希望查询是 unique 键与值的结合。

就像一个物体!

// 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 = {}
}

【讨论】:

  • 这是否允许用户从最近的结果中过滤?
  • 没有。请注意,它只分配给filteredData,从不过滤它。相反,此思想每次都会过滤整个数组,只要选择新的标准,就会添加到查询。 span>
  • 我知道你在那里做了什么。这基本上是在做我正在寻找的东西。请允许我在我的实际应用程序中实现这一点。会回复你,让你知道它是否有效。谢谢
  • 您好 - 过滤器完全按照我的意愿工作。只好稍微上点东西了。我唯一担心的是,经过测试,当不同的用户在不同的计算机上使用该应用程序时,他们会看到其他人正在使用的过滤器。我怎样才能避免这种情况?
  • 过滤器和数据是否保存在一个通用数据库中?这将有资格作为一个新问题,您可以在其中进一步描述系统,但这听起来像是一个具有单个过滤器对象的通用数据库。该修复可能涉及将不同的过滤器对象与每个用户相关联。随意创建一个不同的问题并在这里链接到它。
【解决方案2】:

我认为您应该将过滤器作为数组而不是对象传递:

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

【讨论】:

    【解决方案3】:

    您可以迭代数组并检查每个对象是否满足通过的过滤器。这适用于具有多个元素且每个元素具有多个属性的过滤器。

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

    您也可以根据需要多次拨打filterArr

    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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-28
      • 1970-01-01
      相关资源
      最近更新 更多