【问题标题】:Remove entry from array using another array使用另一个数组从数组中删除条目
【发布时间】:2018-04-10 02:09:36
【问题描述】:

不知道怎么做,非常感谢任何帮助

说我有:

const array1 = [1, 1, 2, 3, 4];
const array2 = [1, 2];

期望的输出

const result = [1, 3, 4];

我希望比较array1array2,对于array2 中的每个条目,从array1 中删除等效项。因此,如果我在 array1 中有 3 of 1,在 array2 中有 1 of 1,则结果数组应该有 2 of 1。

如果这会让事情变得更容易,那么在一个同时包含 jquery 和 underscore.js 的项目上工作。

【问题讨论】:

    标签: javascript jquery arrays underscore.js


    【解决方案1】:

    var array1 = [1, 1, 2, 3, 4],
      array2 = [1, 2],
      result = array1.slice(0);
    
    array2.forEach(function(element) {
      var index = result.indexOf(element)
      if (index >= 0) {
        result.splice(index, 1)
      }
    })
    console.log(result)

    【讨论】:

    • 可爱的算法
    • 那太完美了,而且,我明白发生了什么!
    • 简单就是最好的:)
    【解决方案2】:

    这将运行得相当好。我认为它的线性时间而不是 N*N

    function diffOnlyOncePerElementInstance(a1, a2) {
      const max = Math.max(a1.length, a2.length);
      const map = {};
    
      for (let i = 0; i < max; i++) {
        const valueA = a1[i];
        const valueB = a2[i];
        if (i < a1.length) {
          if (!Number.isInteger(map[valueA])) {
            map[valueA] = 0;
          }
          map[valueA]++;
        }
        if (i < a2.length) {
          if (!Number.isInteger(map[valueB])) {
            map[valueB] = 0;
          }
          map[valueB]--
        }
      }
    
      return Object.keys(map)
        .map(key => new Array(Math.abs(map[key])).fill(key)) // regenerate remaining count
        .reduce((a,b) => a.concat(b), []); // flatten
    }
    

    【讨论】:

      【解决方案3】:

      IMO 使用 array2 作为对象而不是数组将是最高效的方式。

      在第一次找到键时,我们会更改对象中的值,因此我们不会在输出中根据需要再次过滤该值。

      const array1 = [1, 1, 2, 3, 4];
      const array2 = Object.create(null,{
        1:{writable: true,value:false}, 
        2:{writable: true,value:false}
      })
      
      
      let op = array1.filter(e=> {
        if(array2[e] === false){
          array2[e] = true
          return false
        }
        return true
      })
      
      console.log(op)

      旁注:-使用object.create,我们正在创建一个没有原型的对象,因此它不会在完整的原型链中搜索值。

      【讨论】:

      • 可以通过使array2 没有原型来改进这一点(因此JavaScript 引擎不必去寻找原型链上缺少的属性),或者使用Map 而不是一个对象(this answer 从现有的 array2 构建一个 Map,如果您的起点是两个数组,这是一种常见的方法)。
      • @T.J.Crowder 感谢您的意见。我已经更新了答案。
      【解决方案4】:

      您可以尝试以下方法。遍历array1,检查array2的元素是否存在于array1上并拼接出来。

      const array1 = [1, 1, 2, 3, 4];
      const array2 = [1, 2];
      
      
      for(i=0;i<=array1.length;i++){
      
        for(j=0;j<array2.length;j++){
          if(array2[j] == array1[i]){
            array1.splice(i,1);
          }
        }
      
      }
      console.log(array1);

      【讨论】:

        【解决方案5】:

        如果您要使用大型数组,此解决方案的效果会非常好。首先将array1 转换为Map 以便快速查找。然后通过array2 并从您的map 中减去以表示该元素应该被删除。然后最后运行您的map 并添加值大于0 的键

        const array1 = [1, 1, 2, 3, 4];
        const array2 = [1, 2];
        
        const obj = array1.reduce((acc, cv) => {
            if (acc.has(cv)) acc.set(cv, acc.get(cv) + 1);
            else acc.set(cv, 1);
            return acc;
        }, new Map());
        
        array2.forEach(i => {
            if (obj.has(i)) obj.set(i, obj.get(i) - 1);
        });
        
        const res = [];
        obj.forEach((v, k) => { if (v) res.push(k); });
        console.log(res)

        【讨论】:

          【解决方案6】:

          不确定在现代 JS 中最有效的方法是什么,而且我很老派,所以这里有一个老派的解决方案:

           var array1 = [1, 1, 2, 3, 4];
              var array2 = [1, 2];
              
              // Note this method is destructive
              Array.prototype.removeFirstValueMatch = function(ar)
              {
              	var indexesToRemoveAr = [];
              	var indexesToRemoveOb = {};
              	for(var i=0, j; i<ar.length; i++)
              	{
              		for(j=0; j<this.length; j++)
              		{
              			if(this[j] == ar[i] && !indexesToRemoveOb.hasOwnProperty(j) )
              			{
              				indexesToRemoveOb[j] = indexesToRemoveAr.length;
              				indexesToRemoveAr.push(j);
              				break;
              			}
              		}
              	}
              	var descending = indexesToRemoveAr.sort().reverse();
              	for(i=0; i<descending.length; i++)
              	{
              		this.splice(descending[i],1);
              	}
              
              	return this;
              };
          
              // Destructive
              console.log(array1.removeFirstValueMatch(array2));//[1, 3, 4]
              console.log(array1.removeFirstValueMatch(array2));//[3, 4]
          
              // Non-Destructive
              var array1 = [1, 1, 2, 3, 4];
              console.log(array1.slice(0).removeFirstValueMatch(array2));//[1, 3, 4]
              console.log(array1.slice(0).removeFirstValueMatch(array2));//[1, 3, 4]

          【讨论】:

            【解决方案7】:

            您可以使用Map 来计算要移除的项目。

            const
                array1 = [1, 1, 2, 3, 4],
                array2 = [1, 2],
                remove = array2.reduce((m, v) => m.set(v, (m.get(v) || 0) + 1), new Map),
                result = array1.filter(v => !remove.get(v) || !remove.set(v, remove.get() - 1));
            
            console.log(...result);

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2021-07-27
              • 1970-01-01
              • 2013-02-19
              • 1970-01-01
              • 2012-04-18
              • 2020-12-15
              • 1970-01-01
              相关资源
              最近更新 更多