Javascript Filter返回两个对象

Javascript Filter returning two objects

本文关键字:两个 对象 Filter 返回 Javascript      更新时间:2023-09-26

ers,我在这个算法上遇到了一些问题。

我正在使用Redux,尽管我认为这与这个问题并不相关。基本上,这段代码中的console.log语句只返回一个对象,正如它应该返回的那样,但函数A返回两个对象的数组(即使是函数C中没有通过测试的对象(

我把函数分为三个部分,看看这是否能帮助我修复它,但我仍然想不通。

有什么建议吗?

const A = (state) => {
  // looks through an array and passes down a resource
  return state.resources.locked.filter((resource) => {
    return B(state, resource);
  })
};
// looks through an array and passes down a building
const B = (state, resource) => {
  return state.bonfire.allStructures.filter((building) => {
    return C(building, resource);
  })
};
// checks if building name and resource requirment are the same, and if building is unlocked
// then returns only that one
const C = (building, resource) => {
  if (building.unlocked && building.name == resource.requires.structure) {
      console.log(resource);
      return resource;
  }
}

当使用filter时,请注意,传递给它的回调函数应该返回一个布尔值,指示是否需要过滤特定元素。

但在您的情况下,B不返回布尔值,而是返回数组。即使该数组为空(表示没有资源匹配(,filter也不会认为该值为false,因此相应的资源仍将出现在A返回的数组中。

快速修复方法:获取B返回的数组的长度,然后返回该长度。零将被视为错误:

const A = (state) => {
  // looks through an array and passes down a resource
  return state.resources.locked.filter((resource) => {
    return B(state, resource).length;  /// <---- length!
  })
};
// looks through an array and passes down a building
const B = (state, resource) => {
  return state.bonfire.allStructures.filter((building) => {
    return C(building, resource);
  })
};
// checks if building name and resource requirement are the same, and if building
// is unlocked and then returns only that one
const C = (building, resource) => {
  if (building.unlocked && building.name == resource.requires.structure) {
      return resource;
  }
}
// Sample data. Only x matches.
var state = {
    resources: {
        locked: [{ // resource
            requires: {
                structure: 'x'
            }
        }, { // resource
            requires: {
                structure: 'y'
            }
        }]
    },
    bonfire: {
        allStructures: [{ // building
            unlocked: true,
            name: 'x'
        }, { // building
            unlocked: true,
            name: 'z'
        }]
    }
};
console.log(A(state));

但最好是在每个预期的地方都能真正返回布尔值。因此,C应该只返回条件的结果,而B可以使用some而不是filter,这不仅返回布尔值,而且一旦找到匹配,就停止进一步查找。在A中,您现在可以拥有原始代码,因为您确实希望A返回数据(而不是布尔值(。

还需要注意的是,对于只有一个计算表达式的箭头函数,可以使用快捷符号:

  // looks through an array and passes down a resource
const A = state => state.resources.locked.filter( resource => B(state, resource) );
// looks through an array and passes down a building
  // Use .some instead of .filter: it returns a boolean
const B = (state, resource) => 
    state.bonfire.allStructures.some( building => C(building, resource) );
// checks if building name and resource requirment are the same, and if building 
// is unlocked and then returns only that one
  // Return boolean
const C = (building, resource) => building.unlocked 
                               && building.name == resource.requires.structure;
// Sample data. Only x matches.
var state = {
    resources: {
        locked: [{ // resource
            requires: {
                structure: 'x'
            }
        }, { // resource
            requires: {
                structure: 'y'
            }
        }]
    },
    bonfire: {
        allStructures: [{ // building
            unlocked: true,
            name: 'x'
        }, { // building
            unlocked: true,
            name: 'z'
        }]
    }
};
console.log(A(state));