javascript过滤器返回返回错误的值

时间:2018-03-27 12:07:00

标签: javascript reactjs

在我的reactJS应用程序中,我想返回最低级别的元素。元素可能处于同一级别(y坐标)。我只想保留最低的那些。

[ a, b, c  --> (same level - same y-coordinate)
  d, e     --> (same level - same y-coordinate)
  f, g, h] --> (same level - same y-coordinate)

所以我希望能够在这种情况下过滤元素abc。这就是我想出的:

let stepsCopy = [...stepsData];
let steps = [...stepsData].filter((step, index) => {
      return stepsCopy.filter((s, i) => {
             return  step.layout.lg.y < s.layout.lg.y;
      });
});

然而,console.log(steps)显示steps(a,b,c,d,e,f,g,h)中始终存在相同的元素(每个元素)。我在这做错了什么?提前谢谢!

更新“未运行”例子

let stepsData = [
  {"name": "a", "layout": {"lg": {"y": 0}}},
  {"name": "b", "layout": {"lg": {"y": 0}}},
  {"name": "c", "layout": {"lg": {"y": 0}}},
  {"name": "d", "layout": {"lg": {"y": 1}}},
  {"name": "e", "layout": {"lg": {"y": 1}}},
  {"name": "f", "layout": {"lg": {"y": 2}}},
  {"name": "g", "layout": {"lg": {"y": 2}}},
  {"name": "h", "layout": {"lg": {"y": 2}}}
]


let stepsCopy = [...stepsData];

let steps = [...stepsData].filter((step, index) => {
   return stepsCopy.filter((s, i) => {
        return  step.layout.lg.y < s.layout.lg.y
    })
});

console.log(steps);

2 个答案:

答案 0 :(得分:4)

您有两个合乎逻辑的步骤:

  1. 找出最低价值
  2. 过滤数组以仅包含具有该值的元素
  3. 我会在这两个步骤中解决问题:

    let stepsData = [
      {"name": "a", "layout": {"lg": {"y": 0}}},
      {"name": "b", "layout": {"lg": {"y": 0}}},
      {"name": "c", "layout": {"lg": {"y": 0}}},
      {"name": "d", "layout": {"lg": {"y": 1}}},
      {"name": "e", "layout": {"lg": {"y": 1}}},
      {"name": "f", "layout": {"lg": {"y": 2}}},
      {"name": "g", "layout": {"lg": {"y": 2}}},
      {"name": "h", "layout": {"lg": {"y": 2}}}
    ]
    
    const lowestStep = stepsData.reduce((prev, step) => 
      Math.min(prev, step.layout.lg.y), Infinity);
    
    const filteredSteps = stepsData.filter(step => 
      step.layout.lg.y === lowestStep);
    
    console.log(filteredSteps);

答案 1 :(得分:1)

你的过滤器不会有效地完成工作,因为你像疯了一样循环。只需要一个循环来保存最小项目的集合。

所以这背后的想法是一个循环。循环遍历数组并检查值是小于还是相等。如果它更小,则重置并开始在索引处收集。如果相同,只需将其附加到您拥有的列表中即可。如果更大则忽略它。

let stepsData = [
  {"name": "f", "layout": {"lg": {"y": 2}}},  //moved higher values to make sure logic works
  {"name": "a", "layout": {"lg": {"y": 0}}},
  {"name": "b", "layout": {"lg": {"y": 0}}},
  {"name": "c", "layout": {"lg": {"y": 0}}},
  {"name": "d", "layout": {"lg": {"y": 1}}},
  {"name": "e", "layout": {"lg": {"y": 1}}},
  {"name": "g", "layout": {"lg": {"y": 2}}},
  {"name": "h", "layout": {"lg": {"y": 2}}}
]
let stepsCopy = [...stepsData]
let minItems = stepsCopy.reduce((coll, itm) => {  //reduce the collection down to the min y values
  if (!coll.length || coll[0].layout.lg.y === itm.layout.lg.y) {  // if empty or the y's match, add to collection
    coll.push(itm)  // add item to the collection
  } else if (coll[0].layout.lg.y > itm.layout.lg.y) {  // if we find a smaller y in the set, start using that
    coll.length = 0  // reset the collection
    coll.push(itm)   // add the item
    // or instead of keeping same array you can do: return [itm]
  } // else ignore it since it is greater that the min
  return coll  // return the collection for reduce
}, []);
console.log(minItems)