【问题标题】:Javascript filter elements from array which holds elements together from another arrayJavascript过滤数组中的元素,将另一个数组中的元素保存在一起
【发布时间】:2019-01-03 13:36:15
【问题描述】:

我有两个数组。一个喜欢first = ['a','b','c'],另一个喜欢second = ['acd','abd', 'gfa', 'kqb']。我想要做的是从第二个数组返回元素的函数,其中第一个数组的元素一起出现。

例如,函数将返回 ['acd','abd'],因为它们是第二个数组中唯一与第一个数组中的元素一起出现的元素。我需要它在 javascript/typescript 中。

【问题讨论】:

  • 首先,你试过什么?
  • “一起发生”是什么意思?是否是第一个数组中出现的元素中的字符数大于 1?还有什么?
  • @ScottSauyet 是的,这就是我的意思
  • 好的,那么,到目前为止,您尝试了什么? StackOverflow 旨在帮助您解决编码问题,而不是为您编写代码。

标签: javascript typescript loops for-loop while-loop


【解决方案1】:

(请看一下如何改进您在 cmets 中提到的问题。但由于有人已经在这里发布了代码,我更喜欢我的解决方案,就在这里。)

这是一种方法:

const foo = (arr1, arr2) => arr2.filter(str => arr1.reduce(
  (count, char) => count + (str.includes(char) ? 1 : 0), 
  0 
) > 1)

const result = foo(['a', 'b', 'c'], ['abc', 'abd', 'gfa', 'kqb'])

console.log(result)

这里可能存在效率低下的问题,因为即使通过了两个匹配项,它也会继续循环遍历第一个数组。如果结果是一个问题,这将部分缓解这种情况:

  (count, char) => count > 1 ? count : count + (str.includes(char) ? 1 : 0),

这仍然循环,但一旦达到阈值,昂贵的includes 就不再调用。如果您想完全停止循环,您可能必须使用更命令式的方法,例如 for-loop。

【讨论】:

  • reduce 当然是解决这个问题的另一种方法。我个人会通过使用一元运算符将布尔值强制为数字来简化算术表达式:+str.includes(char) + count
  • @Andi:我通常会避免这种强制。但这确实让我意识到这比我写的更干净:(count, char) => str.includes(char) ? count + 1 : count,
  • 为什么要避免这种显式类型强制?
  • 作为记录,我相信reduce 比我使用嵌套filter 方法的解决方案更高效:jsben.ch/HJU3X
  • @Andi:因为布尔值不是数字,也不包含数字;我不喜欢任意映射。我对Number('123') //=> 123 没有意见,因为这似乎合乎逻辑,但我发现+myBoolean 很难解释这对我来说不值得。
【解决方案2】:

此代码可以满足您的需要:

first = ['a','b','c'];
second = ['acd','abd', 'gfa', 'kqb'];

function findOccurencies(first, second) {
  const result = [];
  second.forEach(target => {
    let count = 0;
    first.forEach(source => {
      count += target.indexOf(source) >= 0 ? 1 : 0;
    });
    if (count >= 2) {
      result.push(target);
    }
  });
  return result;
}

console.log(findOccurencies(first, second));

【讨论】:

  • 我相信使用es6 filter 方法是一种更惯用和简化的方法(我的回答如下)。
  • 我同意,es6 filter 更好。这个解决方案是我想到的第一个解决方案
【解决方案3】:

我可能会这样处理:

const first = ['a','b','c'];
const second = ['acd','abd', 'gfa', 'kqb'];

const result = second.filter(
    word => first.filter(char => word.includes(char)).length > 1
);

console.log(result);

【讨论】:

    【解决方案4】:

    这是另一种方式...不优雅,但我认为它可以完成工作...

    const first = ['a','b','c']
    const second = ['acd','abd', 'gfa', 'kqb']
    
    let validated = []
    second.forEach(z=>{
      for(let m = 0; m<=z.length-1; m++){
        let q = first.includes(z[m])
        validated.push(q)
      }
      let count = 0;
      validated.forEach((e,i)=>{
        if(e){
            if(validated[i-1] || validated === []){
                count++;
            }
        }
      })
      validated = []
      if(count !== 0){console.log(z)}
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 1970-01-01
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      相关资源
      最近更新 更多