简体   繁体   English

为什么我的removeNumbersLessThan函数不能正常工作?

[英]Why is my removeNumbersLessThan function not working properly?

I have to write a function that takes a number and an object and input and return an object that has removed all numbers less than the indicated number. 我必须编写一个函数,该函数接受一个数字和一个对象,然后输入并返回一个删除了所有小于指定数字的数字的对象。

I completed a similar function on the previous problem in the problem set that did the opposite, removeNumbersGreaterThan. 我在问题集中的上一个问题上完成了一个类似的功能,该功能相反,即removeNumbersGreaterThan。 All I really did was copy that same code that worked on the previous problem and replaced the greater than symbol with a less than symbol, but for some reason it is not working in all cases. 我真正要做的就是复制处理上一个问题的相同代码,并用小于符号代替大于符号,但是由于某种原因,它并非在所有情况下都有效。

I've already tried changing it to less than or equal to <= but that made no difference at all. 我已经尝试过将其更改为小于或等于<=,但这根本没有区别。 Not sure what's going on! 不知道发生了什么!

 function removeNumbersLessThan(num, obj) { var i = 0; while (i < Object.keys(obj).length) { if (Object.values(obj)[i] < num) { delete obj[Object.keys(obj)[i]] } i++; } return obj; } //test var obj = { a: 4, b: 6, c: 5, d: 3 } removeNumbersLessThan(7, obj) console.log(obj) //returns b:6 d:3 -- should return empty object 

I noticed it returns the second value no matter what. 我注意到无论如何它都会返回第二个值。 Even if it is less than the num value. 即使它小于num值。 After adding some more elements to my object, I noticed that it skips over every other element in the object. 将更多元素添加到对象后,我注意到它跳过了对象中的所有其他元素。 I also found that the reason by previous opposite function worked was because the tests skipped over these cases. 我还发现先前相反功能起作用的原因是因为测试跳过了这些情况。 It also has the same issue, upon further investigation. 经进一步调查,它也有同样的问题。

When your loop deletes a value from obj , that key will no longer be returned from Object.keys . 当循环从obj删除值时,该键将不再从Object.keys返回。
But you still increment the i counter, so you "skip" a key every time you delete a key from obj . 但是您仍然会增加i计数器,因此,每次从obj删除键时,您都会“跳过”键。

You can fix this by only getting the objects keys once and storing them before deleting properties: 您可以通过以下方法解决此问题:仅获取对象键一次,然后在删除属性之前存储它们:

 function removeNumbersLessThan(num, obj) { let keys = Object.keys(obj); for (let key of keys) { if (obj[key] < num) { delete obj[key]; } } return obj; } //test var obj = { a: 4, b: 6, c: 5, d: 3 }; removeNumbersLessThan(7, obj); console.log(obj); 

If you don't want to mutate the object, you could instead copy all properties that are greater than or equal to a new object: 如果您不想突变该对象,则可以复制所有大于或等于新对象的属性:

 function removeNumbersLessThan(num, obj) { let result = {}; for(let [key, value] of Object.entries(obj)) if(value >= num) result[key] = value; return result; } let obj = { a: 4, b: 6, c: 5, d: 3, e: 8 }; console.log(removeNumbersLessThan(7, obj)); 

You mutate the object and get in every loop with a deleted property a new lenght in this vase the index is one ahead. 您对对象进行了变异,并在每个循环中使用已删除的属性在此花瓶中插入了一个新的长度,索引在前面。

This solution is not advisable, because you get for every iteration new keys and values. 建议不要使用此解决方案,因为每次迭代都会获得新的键和值。

 function removeNumbersLessThan(num, obj) { var i = 0; while (i < Object.keys(obj).length) { if (Object.values(obj)[i] < num) { delete obj[Object.keys(obj)[i]]; } else { i++; // increment only if not deleted } } return obj; } var obj = { a: 4, b: 6, c: 5, d: 3 }; removeNumbersLessThan(7, obj); console.log(obj); // {} 

Instead you could get the keys with a for ... in statement . 相反,您可以使用for ... in语句获取密钥。 Then check with this key. 然后用此键检查。

 function removeNumbersLessThan(num, object) { for (let key in object) { if (object[key] < num) { delete object[key]; } } return object; } var obj = { a: 4, b: 6, c: 5, d: 3 }; removeNumbersLessThan(7, obj); console.log(obj); // {} 

First, note that when you delete a key on the object (ie you mutate the object), the length property of the array returned by Object.keys() will decrease in every iteration, at the same time you increment the i variable on every iteration, so in the end you will not traverse all the properties of the object. 首先,请注意,当删除对象上的key (即对对象进行突变)时,由Object.keys()返回的数组的length属性将在每次迭代中减小,同时在每个对象上增加i变量迭代,因此最终您将不会遍历对象的所有属性。

In this particular case, I will prefer using for ... in to traverse the objects keys instead of your while loop, using the next logic: 在这种特殊情况下,我更喜欢使用for ... in遍历对象键,而不是使用以下逻辑进行while循环:

 function removeNumbersLessThan(num, obj) { for (const key in obj) { if (obj[key] < num) delete obj[key]; } return obj; } console.log(removeNumbersLessThan(7, {a:4, b:6, c:5, d:3})); console.log(removeNumbersLessThan(5, {a:4, b:6, c:5, d:3})); 
 .as-console {background-color:black !important; color:lime;} .as-console-wrapper {max-height:100% !important; top:0;} 

Using reduce version... 正在使用简化版本...

function removeNumbersLessThan(num, obj) {
  return Object.keys(obj).reduce((accum, next) => {       
        if (obj[next] >= num)
          return {...accum, [next]: obj[next]};
        else
          return accum;
  },{});
}

      //test
      var obj = {
        a:4,
        b:6,
        c:5,
        d:3
      } 

let x = removeNumbersLessThan(7,obj);

console.log(x);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM