JavaScript groupingDishes问题:代码后半段逻辑解析求助
菜品分组(groupingDishes)问题代码后半段解析
问题需求
给定菜品列表dishes,每个元素以菜名字符串开头,后续为该菜品所需的所有配料字符串。需按配料对菜品进行分组,找出每种配料对应的至少包含它的2道菜品;返回的数组需按配料名称字母序排序,每个子数组以配料名开头,后续菜名也按字母序排序。
示例输入
dishes = [["Salad", "Tomato", "Cucumber", "Salad", "Sauce"], ["Pizza", "Tomato", "Sausage", "Sauce", "Dough"], ["Quesadilla", "Chicken", "Cheese", "Sauce"], ["Sandwich", "Salad", "Bread", "Tomato", "Cheese"]]
示例输出
solution(dishes) = [["Cheese", "Quesadilla", "Sandwich"], ["Salad", "Salad", "Sandwich"], ["Sauce", "Pizza", "Quesadilla", "Salad"], ["Tomato", "Pizza", "Salad", "Sandwich"]]
完整解决方案代码
var a = {}; for (var i=0; i<dishes.length; i++) { for (var j=1; j<dishes[i].length; j++) { a[dishes[i][j]] = (a[dishes[i][j]] || []).concat(dishes[i][0]); } } // 以下是需要解析的部分 return Object.keys(a).sort().filter(function(b) { return a[b].length > 1; }).map(function(b) { return [b].concat(a[b].sort()); });
后半段代码逐行解析
把后半段代码拆分成三个核心步骤理解:
1. Object.keys(a).sort()
Object.keys(a):提取对象a中所有的配料名称(即对象的键),得到一个字符串数组。示例中这一步会得到["Tomato", "Cucumber", "Salad", "Sauce", "Sausage", "Dough", "Chicken", "Cheese", "Bread"]。.sort():对这个配料名称数组按字母顺序排序,排序后变为["Bread", "Cheese", "Chicken", "Cucumber", "Dough", "Salad", "Sauce", "Sausage", "Tomato"]。
2. .filter(function(b) { return a[b].length > 1; })
filter方法遍历排序后的配料数组,只保留满足条件的元素:- 参数
b是当前遍历到的配料名称。 a[b]是该配料对应的菜品列表数组。- 条件
a[b].length > 1表示只保留被至少2道菜品使用的配料。
- 参数
- 示例中这一步会过滤掉
Bread、Cucumber、Dough、Chicken、Sausage这些仅出现在1道菜里的配料,剩下["Cheese", "Salad", "Sauce", "Tomato"]。
3. .map(function(b) { return [b].concat(a[b].sort()); })
map方法把过滤后的每个配料名称转换成符合要求的子数组:- 先创建以当前配料
b为第一个元素的数组[b]。 a[b].sort():把该配料对应的菜品列表按字母顺序排序。比如Cheese对应的菜品["Quesadilla", "Sandwich"]排序后保持原顺序;Salad对应的菜品["Salad", "Sandwich"]排序后也不变。.concat(...):把排序后的菜品列表拼接到配料名称后面,形成最终的子数组。
- 先创建以当前配料
- 示例中这一步会生成符合输出要求的子数组集合,也就是示例输出的结果。
整体流程总结
后半段代码通过提取配料并排序→过滤出符合条件的配料→转换为要求的子数组结构三步,完全满足问题的输出规则:配料按字母序排列,每个子数组以配料开头,后续菜品也按字母序排列,且仅保留被至少2道菜使用的配料。
内容的提问来源于stack exchange,提问作者Muhammad Awais
相关产品推荐
相关产品推荐

