Javascript 根据给定的偏好过滤和返回数组中的元素

Javascript 根据给定的偏好过滤和返回数组中的元素,javascript,arrays,Javascript,Arrays,假设我有两个数组——一个作为顺序的首选项,另一个作为数据集,我想从匹配第一个首选项的数据集中返回第一个元素 比如说 const userPref = ['banana', 'apple', 'peach']; const givenFruits = [ { name: 'apple', color: 'red' }, { name: 'orange', color: 'orange' }, { name: 'pear', color: 'yellow' }, { name: '

假设我有两个数组——一个作为顺序的首选项,另一个作为数据集,我想从匹配第一个首选项的数据集中返回第一个元素

比如说

const userPref = ['banana', 'apple', 'peach'];

const givenFruits = [
  { name: 'apple', color: 'red' },
  { name: 'orange', color: 'orange' },
  { name: 'pear', color: 'yellow' },
  { name: 'cherry', color: 'red' },
  { name: 'grape', color: 'red' },
  { name: 'peach', color: 'red' },
  { name: 'coconut', color: 'brown' }
];

function findFavFruit() {
  userPref.forEach((pref) => {
    givenFruits.forEach((fruit) => {
        if(pref === fruit.name) {
            return fruit;
        }
    });
 });
}

console.log('findFavFruit(): ' + JSON.stringify(findFavFruit(), null, 2));
这总是返回未定义的
。它应该只返回
apple
,因为它是用户首先匹配的首选项,并且在给定的结果中最先找到


在上面的代码中我做错了什么?Javascript中有没有更干净的方法(避免double
forEach
)呢?

您可以使用和循环给定的水果来测试当前水果是否在最喜欢的水果数组中

例如:

函数findFavoriteFruit(首选项、arrayOfFruits){
为了(让水果的果实){
if(首选项.包括(水果.名称)){
还果;
}
}
}
constuserpref=['apple'、'banana'、'peach'];
常量给定结果=[
{名称:'苹果',颜色:'红色'},
{名称:'橙色',颜色:'橙色'},
{名称:'香蕉',颜色:'黄色'},
{名称:'梨',颜色:'黄'},
{名称:'樱桃',颜色:'红色'},
{名称:'葡萄',颜色:'红色'},
{名称:'桃',颜色:'红'},
{名称:'椰子',颜色:'棕色'}
];
const favoriteFruit=findFavoriteFruit(userPref,givenFruits);

console.log(favoriteFruit)您可以使用和循环给定的水果,以测试当前水果是否在最喜爱的水果数组中

例如:

函数findFavoriteFruit(首选项、arrayOfFruits){
为了(让水果的果实){
if(首选项.包括(水果.名称)){
还果;
}
}
}
constuserpref=['apple'、'banana'、'peach'];
常量给定结果=[
{名称:'苹果',颜色:'红色'},
{名称:'橙色',颜色:'橙色'},
{名称:'香蕉',颜色:'黄色'},
{名称:'梨',颜色:'黄'},
{名称:'樱桃',颜色:'红色'},
{名称:'葡萄',颜色:'红色'},
{名称:'桃',颜色:'红'},
{名称:'椰子',颜色:'棕色'}
];
const favoriteFruit=findFavoriteFruit(userPref,givenFruits);

console.log(favoriteFruit)
选择
userPref
数组的第一个元素,将
水果.name
函数中的
进行比较。find()
函数,返回结果

要仅返回属性值,例如,
“name”
,可以将属性作为字符串传递给函数,并使用括号表示法引用和返回属性

constuserpref=['apple','banana','peach'];
const[preference]=userPref;
常量给定结果=[
{名称:'苹果',颜色:'红色'},
{名称:'橙色',颜色:'橙色'},
{名称:'香蕉',颜色:'黄色'},
{名称:'梨',颜色:'黄'},
{名称:'樱桃',颜色:'红色'},
{名称:'葡萄',颜色:'红色'},
{名称:'桃',颜色:'红'},
{名称:'椰子',颜色:'棕色'}
];
函数findFavFruit(pref、prop、arr){
返回arr.find(fruit=>pref==fruit[prop])[prop];
}
let res=findFavFruit(偏好,“名称”,给定果实);

控制台日志(res)
选择
userPref
数组的第一个元素,将
水果.name
函数中的
进行比较。find()
函数,返回结果

要仅返回属性值,例如,
“name”
,可以将属性作为字符串传递给函数,并使用括号表示法引用和返回属性

constuserpref=['apple','banana','peach'];
const[preference]=userPref;
常量给定结果=[
{名称:'苹果',颜色:'红色'},
{名称:'橙色',颜色:'橙色'},
{名称:'香蕉',颜色:'黄色'},
{名称:'梨',颜色:'黄'},
{名称:'樱桃',颜色:'红色'},
{名称:'葡萄',颜色:'红色'},
{名称:'桃',颜色:'红'},
{名称:'椰子',颜色:'棕色'}
];
函数findFavFruit(pref、prop、arr){
返回arr.find(fruit=>pref==fruit[prop])[prop];
}
let res=findFavFruit(偏好,“名称”,给定果实);

控制台日志(res)当然,您应该提供一些检查给定密钥是否存在的方法,但以下是基本方法:

(givenFruits.find((v)=>{return v.name==userPref[0]})).name


如果您只需要第一个键,不知道为什么要迭代
userPref

当然,您应该提供一些检查是否存在给定的键,但以下是基本的:

(givenFruits.find((v)=>{return v.name==userPref[0]})).name


如果您只需要第一个键,我不知道为什么要迭代
userPref

以上所有解决方案都是正确的,我只是想澄清您的代码有什么问题。见下文:

function findFavFruit() {
  let userFruit;
  userPref.forEach((pref) => {
    givenFruits.forEach((fruit) => {
        if(pref === fruit.name) {
            userFruit = fruit;
        }
    });
 });
 return userFruit;
}

如果找到了,这将返回结果;如果没有找到,则返回未定义的结果。

以上所有解决方案都是正确的,我只是想澄清代码的问题所在。见下文:

function findFavFruit() {
  let userFruit;
  userPref.forEach((pref) => {
    givenFruits.forEach((fruit) => {
        if(pref === fruit.name) {
            userFruit = fruit;
        }
    });
 });
 return userFruit;
}

如果找到了,这会返回水果;如果没有找到,则返回未定义的水果。

我只需要
苹果
我想你的意思是
而不是
中的
,但这也不行。这将是
userPref.includes(fruit.name)
I正在更新:)。我在手机上,但我认为使用find会更快。不会的,我已经更新了测试,使用find的实现会慢(2%-5%)。我只需要
apple
我想你的意思是
而不是
中的
,但这也不会起作用。这将是
userPref.includes(fruit.name)
I正在更新:)。我在手机上,但我认为使用find会更快。不会的,我已经更新了测试,使用find的实现会(2%-5%)慢一些。您的
findFavFruit
不会返回任何内容。请记住,
forEach
是一个高阶函数。您的
findFavFruit
不会返回任何内容。记住
forEach
是一个高阶函数。使用find而不是filter,因为只需要第一个对象。如果我没有解释清楚,很抱歉。请参阅仍应返回的更新问题