Javascript 能简单点吗?数组上的map()和filter()

Javascript 能简单点吗?数组上的map()和filter(),javascript,ecmascript-6,Javascript,Ecmascript 6,有没有一种方法可以代替两个函数只编写一个函数并得到相同的结果?为什么map返回未定义的值 让动物=[ {名称:“毛茸茸的”,种类:“兔子”}, {名称:“卡罗”,物种:“狗”}, {名称:“汉密尔顿”,物种:“狗”}, {名称:“哈罗德”,物种:“鱼”}, {名称:“乌苏拉”,物种:“猫”}, {名称:“吉米”,种类:“鱼”} ]; 让animalsNames=animals.map(animal=>{ 如果(动物种类==“狗”){ 返回动物名称; } }); console.log(动物名称

有没有一种方法可以代替两个函数只编写一个函数并得到相同的结果?为什么
map
返回
未定义的值

让动物=[
{名称:“毛茸茸的”,种类:“兔子”},
{名称:“卡罗”,物种:“狗”},
{名称:“汉密尔顿”,物种:“狗”},
{名称:“哈罗德”,物种:“鱼”},
{名称:“乌苏拉”,物种:“猫”},
{名称:“吉米”,种类:“鱼”}
];
让animalsNames=animals.map(animal=>{
如果(动物种类==“狗”){
返回动物名称;
}
});
console.log(动物名称);//[未定义,'Caro','Hamilton',未定义,未定义,未定义]
animalsNames=animalsNames.filter(动物=>animal!==未定义);

console.log(动物名称);//['Caro','Hamilton']
if
条件为非真时,您的
映射将返回
未定义的
值。在这种情况下,没有显式执行
return
语句,这意味着您隐式返回
undefined

有几种解决方案。例如
减少

让动物=[{名字:“毛茸茸的”,物种:“兔子”},{名字:“卡罗”,物种:“狗”},{名字:“汉密尔顿”,物种:“狗”},{名字:“哈罗德”,物种:“鱼”},{名字:“乌苏拉”,物种:“猫”},{名字:“吉米”,物种:“鱼”};
让animalsNames=动物。减少((acc,动物)=>
animal.species==“dog”?acc.concat(动物名称):acc,
[]
);
console.log(动物名称)您可以使用

让动物=[
{名称:“毛茸茸的”,种类:“兔子”},
{名称:“卡罗”,物种:“狗”},
{名称:“汉密尔顿”,物种:“狗”},
{名称:“哈罗德”,物种:“鱼”},
{名称:“乌苏拉”,物种:“猫”},
{名称:“吉米”,种类:“鱼”}
];
常数x=动物。减少((acc,curr)=>{
如果(当前物种=='dog'){
acc.push(当前名称);
}
返回acc;
}, []);

控制台日志(x)在这里,使用过滤器,然后使用映射。 根据您想要的输出进行调整很容易

让动物=[
{名称:“毛茸茸的”,种类:“兔子”},
{名称:“卡罗”,物种:“狗”},
{名称:“汉密尔顿”,物种:“狗”},
{名称:“哈罗德”,物种:“鱼”},
{名称:“乌苏拉”,物种:“猫”},
{名称:“吉米”,种类:“鱼”}
];
const getNames=(物种)=>动物
.filter(({species:s})=>species==未定义的| | s==物种)
.map(({name})=>name);
控制台日志(“狗”);
log(getNames('dog'));
控制台日志(“猫”);
log(getNames('cat');
控制台日志(“全部”);
log(getNames())您完全可以链接(组合)数组方法。有更多关于如何做到这一点的信息

也就是说,我不太了解您的应用程序,但我建议创建一个更实用的函数

例如,您可以指定和/或传递所需的物种作为参数,并返回这些名称的列表

let animals = [
  { name: "Fluffykins", species: "rabbit" },
  { name: "Caro", species: "dog" },
  { name: "Hamilton", species: "dog" },
  { name: "Harold", species: "fish" },
  { name: "Ursula", species: "cat" },
  { name: "Jimmy", species: "fish" }
];

const getAnimalNamesBySpecies = (species) => {
  return animals.filter(animal => animal.species === species).map((animal) => animal.name)
}

console.log(getAnimalNamesBySpecies("dog"))

内置的数组方法不能在一次操作中同时执行
.filter()
.map()
,甚至不能只通过一次数组,但是创建一个实用程序函数,只通过一次数组即可映射和过滤,这可能会更好:

// takes callback(item)
// if return value is undefined, then item is removed from output array
// if return value is anything else, then that becomes the output element
function filterMap(array, callback) {
    let result = [];
    for (let item of array) {
        let r = callback(item);
        if (r !== undefined) {
           result.push(r);
        }
    }
    return result;
}
filterMap(animals, (item) => {
    if (item.species === "dog") {
        return item.name;
    }
});
然后,只需通过阵列一次即可完成操作:

// takes callback(item)
// if return value is undefined, then item is removed from output array
// if return value is anything else, then that becomes the output element
function filterMap(array, callback) {
    let result = [];
    for (let item of array) {
        let r = callback(item);
        if (r !== undefined) {
           result.push(r);
        }
    }
    return result;
}
filterMap(animals, (item) => {
    if (item.species === "dog") {
        return item.name;
    }
});
或者,您可以在此处运行所有代码段:

//接受回调(项)
//若返回值未定义,那个么该项将从输出数组中删除
//如果返回值是其他值,那么它将成为输出元素
函数filterMap(数组、回调){
让结果=[];
for(数组的let项){
设r=回调(项);
如果(r!==未定义){
结果:推(r);
}
}
返回结果;
}
让动物[
{名称:“毛茸茸的”,种类:“兔子”},
{名称:“卡罗”,物种:“狗”},
{名称:“汉密尔顿”,物种:“狗”},
{名称:“哈罗德”,物种:“鱼”},
{名称:“乌苏拉”,物种:“猫”},
{名称:“吉米”,种类:“鱼”}
];
让狗=过滤器映射(动物,(项目)=>{
如果(item.species==“dog”){
返回item.name;
}
});
控制台.日志(狗)