【问题标题】:Replace item in array if they coincides with item from another array如果数组中的项目与另一个数组中的项目重合,则替换它们
【发布时间】:2020-02-15 17:08:09
【问题描述】:

我有一个训练任务来检查数组是否与另一个数组匹配。找到的匹配项必须替换为任何值。

在一种情况下,我做到了,但使用 for...of 时出了点问题 - 我不明白为什么。

//source array
let arr = ['one', 'two', 'three', 'four', 'five', 'six'];

//array to compare
let arrForChange = ['one', 'four', 'six'];

从源数组中更改一项很容易

let changedArr = arr.map(el => { if( el === 'four'){ 
  return el = 4;
  } else { 
  return el = el}  }         
);
// console.log(changedArr); // one,two,three,4,five,six

列表上的替换更有趣一些。这里我使用.includes()

//This variant work 
let cahngedArrFromList = arr.map(el => {
  if(arrForChange.includes(el)){
    return 'A';
  } else {
    return el;
  }  
});
// console.log(cahngedArrFromList); // A,two,three,A,five,A

寻找不同的选项更有趣。这里我使用了for...of,但出了点问题,结果不是我所期望的——只替换了第一个值。

//This variant do not work  =(
let cahngedArrFromListTwo = arr.map(el => { 
  for (const item of arrForChange){
    if (item === el){
      return 'A';
    } else {
      return el;
    }
  }
});
// console.log(cahngedArrFromListTwo); // A,two,three,four,five,six

如果您删除条件else,那么一切似乎都可以正常工作......但没有

let cahngedArrFromListThree = arr.map(el => { 
  for (const item of arrForChange){
    if (item === el){
      return 'A';
    } /* else {
      return el;
    } */
  }
});
// console.log(cahngedArrFromListTree); // A,,,A,,A

你能解释一下for...of 的行为吗?还是我用错了?

【问题讨论】:

  • return 在循环的第一次迭代中。 return 将立即终止循环并退出函数。将return放在循环之后,它将起作用。
  • 为什么是el = el
  • 你的预期输出是什么?

标签: javascript arrays loops for-loop replace


【解决方案1】:

最简单的方法是将索引查找与替换映射结合起来。

如果数组中的当前项在过滤器列表中,则在替换映射中查找其值作为键并返回其值。如果map中不存在key,则返回原值。

const replacements = {
  'one'   : 1,
  'two'   : 2,
  'three' : 3,
  'four'  : 4,
  'five'  : 5,
  'six'   : 6
};

let filter = [ 'one', 'four', 'six' ],
    input  = [ 'one', 'two', 'three', 'four', 'five', 'six' ];

console.log(replaceArrayItem(input, filter, replacements));

function replaceArrayItem(arr, filterArr, replMap) {
  return arr.map(item => filterArr.indexOf(item) > -1 ? replMap[item] || item : item);
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

【讨论】:

  • 谢谢你,但是我还没有读过关于对象的内容)我会在仔细研究对象的主题后尝试你的方法。
【解决方案2】:

我认为这是因为当您进行第一次检查时,您是在比较

"one" === "one" // will return 'A'

您返回后不再检查“one”。

然后 "one" === "two" // will return el

因为你又回到了这一点,所以你永远不会检查"four" === "two"等。

这对于之后的每次检查都是一样的。因为您在第一次检查发生后返回,所以您永远不会找到任何其他匹配项。通过删除第二次返回,您可以继续搜索整个数组以找到匹配项。

如果您在没有第二次返回的情况下运行

let changedArrFromListThree = arr.map(el => {
  for (const item of arrForChange) {
    console.log("doesMatch? " + item + " " + el);
    if (item === el) {
      console.log("MATCH");
      return "A";
    } else {
      // return el;
    }
  }
});

输出是

doesMatch? one one 
MATCH
doesMatch? one two
doesMatch? four two
doesMatch? six two
doesMatch? one three
doesMatch? four three
doesMatch? six three
doesMatch? one four
doesMatch? four four
MATCH
doesMatch? one five
doesMatch? four five
doesMatch? six five
doesMatch? one six
doesMatch? four six
doesMatch? six six
MATCH
[ 'A', undefined, undefined, 'A', undefined, 'A' ]

当你使用第二次返回时

let changedArrFromListThree = arr.map(el => {
  for (const item of arrForChange) {
    console.log("doesMatch? " + item + " " + el);
    if (item === el) {
      console.log("MATCH");
      return "A";
    } else {
      return el;
    }
  }
});

输出是

doesMatch? one one
MATCH
doesMatch? one two
doesMatch? one three
doesMatch? one four
doesMatch? one five
doesMatch? one six
[ 'A', 'two', 'three', 'four', 'five', 'six' ]

这样可以更清楚地了解正在发生的事情。

【讨论】:

  • 谢谢!您的解释有助于理解for ... of 中发生的事情。正如@VLAZ 在评论中所写,我在循环之后执行return,我得到了正确执行的函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 2011-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2019-08-11
相关资源
最近更新 更多