使用lambda函数在包含对象数组的对象数组中查找JavaScript对象

时间:2017-02-12 15:07:39

标签: javascript arrays object find

假设我有一个看起来像这样的javascript对象:

var events = 
[
    {
        name: "Foo event",
        submissions: [
            {
                id:"sub1",
                name:"First submission"
            },
            {
                id:"sub2",
                name:"Second submission"
            }
        ]
    },
    {
        name: "Bar event",
        submissions: [
            {
                id:"sub3",
                name:"First submission in bar"
            },
            {
                id:"sub4",
                name:"Second submission in bar"
            }
        ]
    }
]

我希望能够编写一个lamba函数,例如返回整个对象

{
    id:"sub4",
    name:"Second submission in bar"
}

鉴于身份sub4。像var submission = events.magicLamba(...)这样的东西我尝试使用Array.prototype.find,但是如果我必须从一个对象数组中选择一个对象,那么这就有用了,在这种情况下,还有一个搜索对象。

感谢您的帮助。

编辑:正如你们许多人所指出的那样,事件无效。它确实是一个数组,在尝试编写原始数据的简单示例时,我必须误写它。

5 个答案:

答案 0 :(得分:2)

首先,您的“事件”无效。看起来它应该只是一个数组,在这种情况下,您应该只删除最外面的{ }

由于您在示例中使用了“id”,因此我假设每个提交ID都是唯一的。

虽然你可以使用.foreach(),但是没有办法打破foreach,所以你最终会评估每次提交 - 即使你找到了你想要的那个。

因此,我会使用for循环,一旦找到我要找的东西就会爆发。这样会更有效率。我添加了一些控制台日志记录,因此您可以看到,一旦找到所需内容,就不会继续评估数据。

    var events = [
        {
            name: "Foo event",
            submissions: [
                { id: "sub1", name: "First submission"},
                { id: "sub2", name: "Second submission"}
            ]
        },
        {
            name: "Bar event",
            submissions: [
                { id: "sub3", name: "First submission in bar" },
                { id: "sub4", name: "Second submission in bar"}
            ]
        }
    ];

    function findSubmission(events, submissionId) {
        var result = null;
        for (var event of events) {
            console.log("new event evaluated");
            for (var submission of event.submissions) {
                console.log("evaluating submission: ",submission.id);
                if (submission.id === submissionId) {
                    result = submission;
                    break;
                }
            }
            if (result) break;
        }
        return result;
    };

    var matchingSubmission = findSubmission(events, "sub3");

答案 1 :(得分:1)

好吧,就像我评论过您的数据似乎无效

events = { [] } // is not correct syntax.
也许它应该是events = []

好吧,让我们想象它是一个数组,至少是有意义的。

findSubmission看起来像这样:

function findSubmission(events, submissionId) {
  var result;
  events.forEach(function(event) {
    event.submissions.forEach(function(submission) {
      if (submission.id === submissionId) {
        result = submission;
      }
    })
  });

  return result;
}

submission = findSubmission(events, "sub4");

答案 2 :(得分:1)

您可以使用some来实现您想要的效果:



var events = [{name: "Foo event",submissions: [{id:"sub1",name:"First submission"},{id:"sub2",name:"Second submission"}]},{name: "Bar event",submissions: [{id:"sub3",name:"First submission in bar"},{id:"sub4",name:"Second submission in bar"}]}]

function find(arr, id) {
  var res;                          // uninitialized thus the result will be undefined if nothing is found
  arr.some(                         // unlike forEach some will stop after the first match (after the first callback call that returned true)
    o => o.submissions.some(
      o => o.id == id && (res = o)  // return true if o.id == id, false otherwise (and if o.id == id then assign o to result)
    ) 
  );
  return res;
}

console.log(find(events, "sub2"));
console.log(find(events, "sub4"));
console.log(find(events, "sub499999"));




答案 3 :(得分:0)

您正确地注意到 <?php /** * @file * The PHP page that serves all page requests on a Drupal installation. * * All Drupal code is released under the GNU General Public License. * See COPYRIGHT.txt and LICENSE.txt files in the "core" directory. */ use Drupal\Core\DrupalKernel; use Symfony\Component\HttpFoundation\Request; $autoloader = require_once 'autoload.php'; $kernel = new DrupalKernel('prod', $autoloader); $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response); 仅帮助您从提交数组中获取提交。您可以使用另一个嵌套循环find(),它将返回嵌套map()调用的所有结果。作为最后一步,您需要从结果数组中删除所有未定义的值。

find()

答案 4 :(得分:0)

我找到了一种对我有用的有趣方式。它只使用lambda函数(即some和find),看起来效率很高。

function findSubmissionUsingSome(events, submissionId){
    var submission;
    events.some(event => {
        submission = event.submissions.find(s => s.id === submissionId); //search for the submission in the current event, and store it in a variable
        return submission; //returns truthy value if submission is found and exits some
    });
    return submission;
}

你可以看到测试运行here,我不确定它为什么表现如此之好,并且想要一些澄清(也许它可以并行工作?)。非常感谢RobM测试代码。