尝试编写JavaScript的filter方法的反向版本,可用于数组和对象。

huangapple go评论59阅读模式
英文:

Trying to write a inverse version of Javascript's filter method that will work on both arrays and objects

问题

以下是您提供的代码的翻译部分:

// 翻译后的代码
function reject(collection, callback) {
  let newArr;
  if (!collection.constructor == Array) {
    newArr = {};
    for (let [key, value] of Object.entries(collection)) {
      if (!callback(value)) {
        newArr[key] = value;
      }
    }
  } else {
    newArr = [];
    for (let el of collection) {
      if (!callback(el)){
        newArr.push(el);
      }
    }
  }
  return newArr;
}
英文:

So as the question states, I'm attempting to write a function for which the input can be either an Array or an Object (as well as a callback to test them against).

The desired return value is an Array / Object of the elements (value/key pairs in the case of the Object) that passed the test - but the original Array / Object should be updated to remove those elements.

For example - if you passed in an "isEven" callback function that determines if numbers are even, then the expected results would be:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let a = [1, 2, 3, 4]
reject(a)

//Output:
[2, 4]


console.log(a);
//expected output
[1, 3]

<!-- end snippet -->

So far I've been trying to write an conditional scenario based on Array.isArray(input), to use one set of code for handling arrays, another set for handling objects. However, it's been not working properly for objects, and I'm curious if there'd be one way to write it that would work for both cases? If not what might be the best approach here?

My rough attempt to this point, if the code is helpful:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function reject(collection, callback) {
  let newArr;
  if (!collection.constructor == Array) {
    newArr = {};
    for (let [key, value] of Object.entries(collection)) {
      if (!callback(value)) {
        newArr[key] = value;
      }
    }
  } else {
    newArr = [];
    for (let el of collection) {
      if (!callback(el)){
        newArr.push(el);
      }
    }
  }
  return newArr;
}

<!-- end snippet -->

答案1

得分: 1

可以使用 Array.isArray 来检查一个对象是否为数组。要从数组中移除元素,你可以倒序迭代并使用 Array#splice

function reject(o, f) {
  if (Array.isArray(o)) {
    let res = [];
    for (let i = o.length - 1; i >= 0; i--)
      if (f(o[i])) res.push(o.splice(i, 1)[0]);
    return res.reverse();
  }
  let res = {};
  for (const [k, v] of Object.entries(o)) 
    if (f(v)) {
      res[k] = v;
      delete o[k];
    }
  return res;
}
let a = [1, 2, 3, 4];
console.log(reject(a, x => x % 2 === 0), a);
let obj = {a : 1, b : 2, c : 3, d : 4};
console.log(reject(obj, x => x > 2), obj);
英文:

You can use Array.isArray to check if an object is an array. To remove elements from the array, you can iterate backwards and use Array#splice.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function reject(o, f) {
  if (Array.isArray(o)) {
    let res = [];
    for (let i = o.length - 1; i &gt;= 0; i--)
      if (f(o[i])) res.push(o.splice(i, 1)[0]);
    return res.reverse();
  }
  let res = {};
  for (const [k, v] of Object.entries(o)) 
    if (f(v)) {
      res[k] = v;
      delete o[k];
    }
  return res;
}
let a = [1, 2, 3, 4];
console.log(reject(a, x =&gt; x % 2 === 0), a);
let obj = {a : 1, b : 2, c : 3, d : 4};
console.log(reject(obj, x =&gt; x &gt; 2), obj);

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月18日 04:41:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75489077.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定