【问题标题】:Javascript Filter returning two objectsJavascript过滤器返回两个对象
【发布时间】:2016-09-17 19:52:26
【问题描述】:

人, 我在使用这个算法时遇到了一些问题。

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

我将函数分成 3 个部分,看看这是否能帮助我修复它,但我仍然无法弄清楚。

有什么建议吗?

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;
  }
}

【问题讨论】:

  • 请提供样品state

标签: javascript ecmascript-6 redux


【解决方案1】:

使用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));

【讨论】:

    猜你喜欢
    • 2018-10-05
    • 2020-09-03
    • 2017-12-06
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 2022-01-21
    相关资源
    最近更新 更多