【问题标题】:Trying to return a deep nested object with Lodash尝试使用 Lodash 返回深层嵌套对象
【发布时间】:2016-06-15 20:37:01
【问题描述】:

我无法在 StackoverlFlow 上找到解决方案,我一直在研究这个问题一段时间。这有点困难,所以如果我应该提供更多信息,请告诉我。

我的问题: 我有一个土地的 JSON 对象,每个土地都有一个 ID 和一个与之关联的 Blocks 数组,并且该 blocks 数组也有带有 ID 的块。

预览:

var Lands = [{
                'LandId':'123',
                'something1':'qwerty',
                'something2':'qwerty',
                'Blocks': [
                    {
                        'id':'456',
                        'LandId':'123'
                    },
                    {
                        'BlockId':'789',
                        'LandId':'123'
                    }
                ]
            },
            ...More Land Objects];

注意:数据没有按照我的方式设置,但这是很久以前完成的,我必须使用我现在拥有的东西。

我正在尝试编写一个 lodash 函数,它将获取我拥有的 blockId 并匹配它们并从 Blocks 返回landId。

所以最终结果将是从 Blocks 返回的 LandId 列表。

我正在使用这样的东西,但它没有返回任何结果:

selectedLand = function(Lands, landIDs){
                return _.filter(Lands, function(land){
                    return land === landIDs[index];
                });
            };

我知道我正在以错误的方式解决这个问题,并且想知道解决这个问题的适当方法。非常感谢任何帮助。

【问题讨论】:

    标签: javascript angularjs lodash


    【解决方案1】:
    selectedLand = function(Lands, landIDs){
                    return _.filter(Lands, function(land){
                        return land === landIDs[index];
                    });
                };
    

    请注意,index 在此范围内没有任何定义,因此该函数基本上永远不会返回 true,除非与外部定义的 index 发生幸运(?)事故。无论何时您拨打_.filter(someArr,function(){return false;}),您都会收到[]。除了未定义的index,这确实将陆地对象与(可能)土地ID中的字符串进行了严格比较

    我对您选择的确切要求有点不清楚,因此您可以根据自己的需要定制此过滤器。函数过滤 lands 数组,方法是检查.blocks 数组属性是否具有一些 值,其中.landID 属性包含 landsID 数组。

    最后,如果您想充分利用lodash(或我最喜欢的ramda.js),我建议您坐下来阅读docs。听起来很无聊,但 75% 的数据转换战斗是知道你的工具箱里有什么。注意过程的英文描述与示例代码(过滤器、一些、包含)几乎完全匹配。

    var Lands = [{
        'LandId': '123',
        'something1': 'qwerty',
        'something2': 'qwerty',
        'Blocks': [{
          'id': '456',
          'LandId': '123'
        }, {
          'BlockId': '789',
          'LandId': '123'
        }]
      }
    ];
    
    // assuming lands is like the above example
    // and landIDs is an array of strings
    var selectLandsWithBlocks = function(lands, landIDs) {
      return _.filter(lands, function(land) {    
        var blocks = land.Blocks;
        var blockHasALandId = function(block) {
          return _.includes(landIDs,block.LandId);
        };
        return _.some(blocks, blockHasALandId);
      });
    };
    
    console.log(selectLandsWithBlocks(Lands,[]));
    console.log(selectLandsWithBlocks(Lands,['mittens']));
    console.log(selectLandsWithBlocks(Lands,['123']));
    <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>

    【讨论】:

    • 这是一个很好的例子,我现在正在研究文档,lodash 和 ramda.js 之间的真正区别是什么?
    • @Keeano 它们可以以类似的方式使用。 Lodash 更受欢迎并且有更多的辅助函数(比如 _.camelCase)并且不能咖喱所有东西(它可以在某种程度上。但不是所有东西)。 Ramda 是一个实用的函数库,因此您可以非常轻松地对函数进行 curry 和 pipe。 Here's the same solution with ramda.。有一些样板,但归结为列出|> R.filter |> R.any |> R.contains 。与 lodash 非常相似(因为它的逻辑相同),但 Ramda 变得更容易,因为您需要使用更复杂的转换进行扩展。
    • 我遇到了一个涉及此问题的问题,并且没有找到解决方法...如果我可以向您提供我的电子邮件,您能帮我吗?我已经阅读了您所描述的文档,但我仍然得到一个奇怪的回报......我正在使用您的过滤器并稍微调整它以获得其他东西。
    • @Keeano 当然,但没有承诺。如果这不仅仅是一个快速修复,我会做咨询工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多