【问题标题】:Refining results of an array优化数组的结果
【发布时间】:2018-03-06 00:12:21
【问题描述】:

我正在返回来自 firebase 查询的结果。结果是一组具有不同属性的对象。这是我正在制作的汽车应用程序。每个对象看起来像这样

{
   make: "make",
   model: "model",
   year: "year",
   gas: "petrol",
   mileage: "mileage",
   images: {
       image1: "url",
       image2: "url"
   }
}

我需要让用户能够改进这些结果,并且我正在尝试提出一个可靠的解决方案

问题: 我需要用户能够细化 firebase 查询的结果。 用户将为他们的细化搜索选择不同的选项,所以我需要我的函数来处理这个

我在做什么

//Heres' how I planned to pass the refinement options
refinements = {
    make: 'value',
    model: 'value',
    year: 'value'
}

//currentResults is an array of objects with different properties

const refineResults = (currentResults, refinements) => {

    newResults = [];

    for (int i = 0; i < currentResults.count; i++ ){

        let currentResult = currentResult[i];

        for(int i = 0; i < refinements.count; i++){

        }
    }
}

我知道我对这个功能还不是很了解,但我什至不确定我是否以正确的方式接近这个功能。我不确定如何通过 for 循环访问属性值,作为细化。[I] 比较没有意义

我基本上想遍历我当前的结果,如果我的优化对象中的所有值都相等,那么我想将此结果添加到我的新结果数组中。

感谢您的任何意见

【问题讨论】:

  • firebase 不能接受查询?你为什么要处理“改进”?
  • 你能告诉我们currentResults的数据吗?你说它是一个具有不同属性的箭头......听起来它是一个对象。如果你试图循环一个对象,你可能会遇到问题。
  • 根据我的理解,您可能需要考虑使用filterThere's an example using JSON on MDN
  • 是的,firebase 可以接受查询,但是我已经在执行 firebase 查询以获得初始结果。我还想保留旧结果和新结果,以便我的用户可以选择根据不同的值优化结果@Stretch0 是的,currentResults 数据是一个对象数组,与我帖子开头的对象完全一样。我在一个数组中返回大约 100 个这些对象。谢谢
  • @Icepickle:OP 很可能希望过滤多个属性。 Firebase 数据库查询只能对单个属性进行排序/过滤。在许多情况下,可以将要过滤的值组合成单个(合成)属性。有关此方法和其他方法的示例,请在此处查看我的答案:stackoverflow.com/questions/26700924/…。但是,如果无法在查询中完成过滤,那么在代码中进行过滤可能是唯一剩下的选择。当然:在这种情况下,注意带宽使用是关键。

标签: javascript reactjs firebase-realtime-database


【解决方案1】:

这样的事情可以解决问题:

refinements = {
    make: 'Toyota',
    model: 'RAV4',
    year: '2010'
}

var currentResults = [
  { make: 'Toyota', model: 'Matrix', year: '2012' },
  { make: 'Toyota', model: 'RAV4', year: '2010' },
  { make: 'Chevrolet', model: 'Matiz', year: '2000' }
];

//currentResults is an array of objects with different properties

const refineResults = (currentResults, refinements) => {
    return currentResults.filter((car) => {
        /*var result = true;
        Object.keys(refinements).forEach(refinement => {
            if (car[refinement] !== refinements[refinement]) result = false;
        });
        return result;*/
        return !Object.keys(refinements).some(refinement => car[refinement] !== refinements[refinement]);

    });
}

console.log(refineResults(currentResults, refinements));

使用的关键概念:

  • 代码使用Array.filter 将当前结果过滤到仅与优化匹配的结果。
  • 代码使用Object.keys 来确定优化的键(makemodelyear),以便它可以用Array.some(或注释掉的Array.forEach)循环它们)。
  • *

【讨论】:

  • 吹毛求疵:你的意思是Array.prototype.filterforEach 一样。
  • 感谢@FrankvanPuffelen 的详细回复,这看起来正是我所需要的。我不完全理解 Object.keys 和 Array.some 但会立即调查所以我完全理解正在发生的事情。干杯
【解决方案2】:

我不确定您希望refinements 对象如何工作,但我假设您需要每个结果中的每个属性都等于每个result 中的相应属性。在这种情况下,下面的refineResults 函数会有所帮助。

// helper func, returns true only if all props on `refinements` match their counterparts on `result`
function matchesAll(refinements, result) {
  for (const key in refinements) {
    if (refinements[key] !== result[key]) {
      return false;
    }
  }
  return true;
}

// returns filtered list of results
function refineResults(currentResults, refinements) {
  return currentResults.filter(result => matchesAll(refinements, result));
}

【讨论】:

  • 感谢您回复阿伦。此功能看起来很棒,是其他解决方案的不错替代品。将调查这两个答案
【解决方案3】:

使用过滤器,可以实现给定的要求,并且可以将更多过滤业务逻辑作为参数传递给函数,例如大于,小于和更多。试试看。

下面是实现相同目的的简单代码。

var results = [
  {name:"john",age:15,price:400},
  {name:"joe",age:25,price:450},
  {name:"johnson",age:35,price:500}
];
var refine = {name:"john",age:15};

var result = results.filter(function(val){
	return val.name === refine.name && val.age == refine.age;
});

console.log(result);

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多