首页 > 解决方案 > JavaScript 数组:有没有一种方法可以在拼接和过滤器之间进行交叉处理?

问题描述

我有一个对象数组,并且想要:

  1. 从数组中删除某些对象
  2. 在第二步中处理移除的对象

我事先不知道这些物体在哪里。为了识别它们,我需要使用一个查询它们的属性的函数。在第二个数组中检索已删除的对象是有意义的。

我曾希望找到一种类似filtersplice那样的本机方法。这是我提出的解决方案:

if (!Array.prototype.cherrypick) {
  Array.prototype.cherrypick = function(fn) {
    let basket = []
    let ii = this.length
    let item

    for ( ; ii-- ; ) {
      item = this[ii]

      if (fn(item)) {
        basket.unshift(item)
        this.splice(ii, 1)
      }
    }

    return basket
  }
}

我错过了什么吗?是否已经有一种本机方法可以做到这一点?我的解决方案在某些方面不合理吗?

标签: javascriptarraysfiltering

解决方案


诸如Array.filter()返回一个新数组而不是更改原始数组的方法。

您可以使用它创建一个分区方法Array.reduce(),该方法将返回两个数组 - 那些通过谓词的数组和那些失败的数组:

const partition = (predicate, arr) =>
  arr.reduce((r, o) => {
    r[+!!predicate(o)].push(o);
    
    return r;
  }, [[], []]);
  
const arr = [4, 8, 3, 10, 12];

const result = partition(n => n > 5, arr);

console.log(result);

您可以使用分区逻辑Array.splice()来创建cherrypick方法:

if (!Array.prototype.cherrypick) {
  Array.prototype.cherrypick = function(predicate) {
    const [removedItems, items] = arr.reduce((r, o) => {
      r[+!!predicate(o)].push(o);

      return r;
    }, [[], []]);
    
    this.splice(0, arr.length, items);
    
    return removedItems;
  }
}

const arr = [4, 8, 3, 10, 12];

const removed = arr.cherrypick(n => n > 5);

console.log('arr ', arr);

console.log('removed ', removed);


推荐阅读