我有一个数组:var old_array = [1, 2, 3, 4, 5]
如果此数组中存在5
,请将其删除,否则将其添加。
var new_array = [];
var number_existed = false;
for(var i=0,len=old_array.length;i<len;i++) {
if(old_array[i] == 5) {
new_array = old_array.slice(i+1);
number_existed = true;
break;
} else {
new_array.push( old_array[i] );
}
}
if(!number_existed) {
new_array.push(5);
}
可以,但是我需要改进。如何改善此代码。我想看看reduce
函数的作用,但无法提出任何合乎逻辑的内容。
答案 0 :(得分:3)
您可以检查元素是否已经存在Array.includes
,然后Array.filter
将其删除,或使用spread syntax附加它:
function addOrRemove5(arr) {
return arr.includes(5) ? arr.filter(v => v !== 5) : [...arr, 5];
}
console.log(addOrRemove5([1, 2, 3, 4, 5]));
console.log(addOrRemove5([1, 2, 3, 4]));
答案 1 :(得分:1)
let fiveFound = false;
const result = input.filter(it => it !== 5 || !(fiveFound = true));
if(!fiveFound) result.push(5);
reduce
在这里无济于事。
答案 2 :(得分:1)
使用reduce
并不是最佳方法,因为使用reduce可以返回单个项目。在我的解决方案中,我使用findIndex并应用您的逻辑。
function usingFunctions(old) {
var index = old.findIndex( function(it) { return it == 5 } );
var new_arr = old.slice( index + 1 );
if( index < 0 ) new_arr.push(5);
return new_arr
}
var old = [1, 2, 6, 8, 5, 3, 6, 9];
console.log( usingFunctions(old) );
old = [1, 2, 6, 8, 3, 6, 9];
console.log( usingFunctions(old) );
答案 3 :(得分:1)
另一个解决方案,扩展我的评论:
Jeto的答案应该可以解决这个问题。没有真正的理由为此使用reduce,因为这会使事情变得复杂。如果您只是过滤掉现有的5,则
reduce
将是filter
的一个过于复杂但并非不合理的选择。但是由于您还想添加一个不存在的5,因此累加器将需要携带额外的状态-否则您会将其存储在更糟糕的地方。这样的代码是可行的,但与其他方法相比却很丑陋。
以下是这些丑陋的代码的样子:
const addOrRemove5 = (arr) => {
const {found, xs} = arr.reduce(
({found, xs}, x) => x === 5 ? {found: true, xs} : {found, xs: [...xs, x]},
{found: false, xs: []}
)
return found ? xs : [...xs, 5]
}
console.log(addOrRemove5([1, 5, 2, 3, 4, 5])) //=> [1, 2, 3, 4]
console.log(addOrRemove5([1, 2, 3, 4])) //=> [1, 2, 3, 4, 5]
这使用了一个看起来像{found: boolean, xs: [number]}
的累加器,从{found: false, xs: []}
开始,在每个found
上将true
更新为5
,然后将每个非5的值。然后,运行之后,我们将根据5
的值返回现有值或现有值以及一个附加的found
。
同样,这比Jeto的解决方案难看得多。我在这里不推荐。但是,当您需要携带其他信息并减少价值时,此类技术并不少见。通过将生成的{found, xs}
对象放在默认参数中,这样的变体可以让您仅使用表达式而不使用任何语句:
const addOrRemove5 = (
arr,
{found, xs} = arr.reduce(
({found, xs}, x) => x === 5 ? {found: true, xs} : {found, xs: [...xs, x]},
{found: false, xs: []}
)
) => found ? xs : [...xs, 5]
在这种情况下,不建议再次这样做,但这是一个有用的技巧。
答案 4 :(得分:0)
您不需要reduce()
,只需使用filter()
var old_array = [1, 2, 3, 4, 5]
var new_array = old_array.filter(x => x === 5);
console.log(new_array);
答案 5 :(得分:0)
您可以使用indexOf
找到它以获取索引,然后使用splice
删除它,或者使用push
添加它
var array1 = [1, 2, 3, 4, 5]
function modify_array(value, array) {
let idx = array.indexOf(value)
idx > -1 ? array.splice(idx, 1) : array.push(value)
return array
}
// Test cases
// Remove 5
console.log(modify_array(5, array1))
// Add 10
console.log(modify_array(10, array1))
答案 6 :(得分:0)
如果您真的要使用reduce()
:
function togglePresenceOfFive(array) {
if (array.length === 0) { // Reduce can't handle this case because the loop never runs
return [5];
} else {
const reduceResult = array.reduce((acc, next, index, arr) => {
const isLast = index === arr.length - 1;
if (next === 5) {
return {
newArray: acc.newArray,
fiveFound: true
};
} else if (!acc.fiveFound && isLast) {
return {
newArray: acc.newArray.concat(next, 5),
fiveFound: false
}
} else {
return {
newArray: acc.newArray.concat(next),
fiveFound: acc.fiveFound
};
}
},
{ newArray: [], fiveFound: false }
);
return reduceResult.newArray;
}
}
return reduceResult.newArray;
}
但这在我看来更容易理解(假设您不介意更改原始数组):
function togglePresenceOfFive(array) {
const indexOfFive = array.indexOf(5);
if (indexOfFive > -1) {
array.splice(indexOfFive, 1);
} else {
array.push(5);
}
return array;
}