【问题标题】:Filtering a list of Objects with lists- Javascript使用列表过滤对象列表 - Javascript
【发布时间】:2014-08-14 02:50:24
【问题描述】:

过滤包含列表对象的列表最有效的方法是什么。我一直在看下划线的 _.filter 函数,但这需要数组并返回数组。

我想取一个对象并用某个词过滤它。

例如,我将如何过滤:

    [
{level: "Title 1", details: [
    {real: "There we go", fake: "THERE_WE_GO"},
    {real: "Where is it", fake: "WHERE_IS_IT"},
    {real: "The dog jumped", fake: "THE_DOG_JUMPED"},
] }, 
{level: "Title 2", details: [
    {real: "There it is", fake: "THERE_IT_IS"},
    {real: "Car is flying", fake: "CAR_IS_FLYING"},
    {real: "Driving is fun", fake: "DRIVING_IS_FUN"}
] }, 
{level: "Title 2", details: [
    {real: "There he is", fake: "THERE_WE_GO"},
    {real: "Where is the dog", fake: "WHERE_IS_THE_DOG"},
    {real: "The dog died", fake: "THE_DOG_DIED"},
    {real: "I am tired", fake: "I_AM_TIRED"},

]}
];

用“那个”这个词

这样它会返回

    [
{level: "Title 1", details: [
    {real: "There we go", fake: "THERE_WE_GO"},
    {real: "The dog jumped", fake: "THE_DOG_JUMPED"},
] }, 
{level: "Title 2", details: [
    {real: "There it is", fake: "THERE_IT_IS"},
] }, 
{level: "Title 2", details: [
    {real: "There he is", fake: "THERE_WE_GO"},
    {real: "Where is the dog", fake: "WHERE_IS_THE_DOG"},
    {real: "The dog died", fake: "THE_DOG_DIED"},
]}
];

请注意,当按“the”这个词过滤时,我还想保留任何包含“the”这个词的东西,比如“There”……我只去检查“the”这个词是否" 位于细节数组内对象的“真实”索引中。

【问题讨论】:

  • 那不是一个对象,而是一个对象数组。因此,下划线过滤对您来说效果很好。你当然需要编写过滤函数。您是否进行过任何可以显示代码的尝试?
  • ES5中有一个内置的filter,为什么需要underscore.js呢?

标签: javascript arrays object underscore.js javascript-objects


【解决方案1】:

您可以使用filter,但您必须在每个内部列表和外部列表上应用一次:

var phrase = "the".toUpperCase();
return _.filter(_.map(data, function(item) {
    return {
        level: item.level,
        details: _.filter(item.details, function(detail) {
            return detail.fake.indexOf(phrase) > -1;
        })
    };
}), function(item) {
    return item.details.length > 0;
});

从您的示例中,我无法推断您是否需要外部 filter,或者您是否不想删除包含空详细信息列表的项目。

【讨论】:

    【解决方案2】:

    这是使用纯 javascript 的解决方案:

        var arr = [
        {level: "Title 1", details: [
            {real: "There we go", fake: "THERE_WE_GO"},
            {real: "Where is it", fake: "WHERE_IS_IT"},
            {real: "The dog jumped", fake: "THE_DOG_JUMPED"},
        ] },
        {level: "Title 2", details: [
            {real: "There it is", fake: "THERE_IT_IS"},
            {real: "Car is flying", fake: "CAR_IS_FLYING"},
            {real: "Driving is fun", fake: "DRIVING_IS_FUN"}
        ] },
        {level: "Title 3", details: [
            {real: "There he is", fake: "THERE_WE_GO"},
            {real: "Where is the dog", fake: "WHERE_IS_THE_DOG"},
            {real: "The dog died", fake: "THE_DOG_DIED"},
            {real: "I am tired", fake: "I_AM_TIRED"},
    
        ]}
    ];
    function filterArr(arr, str) {
        var ret = new Array();
        for (var i = 0; arr[i]; i++) {
            var obj = arr[i].details;
            ret[i] = new Object();
            ret[i]['level'] = arr[i].level;
            ret[i]['details'] = [];
    
            for (var j = 0; obj[j]; j++) {
                if (obj[j].real.toLowerCase().indexOf(str.toLowerCase()) != -1) {
    
                    ret[i].details.push(obj[j]);
                }
    
    
            }
        }
        return ret;
    }
    console.log( filterArr(arr, 'the'));
    

    【讨论】:

    • 您可以使用 ret[i] = {level:arr[i].level, details:[]}; 将 3 行替换为 1。 :-)
    【解决方案3】:

    这是另一个“普通”的 javascript 解决方案。它试图最小化硬编码的属性,但这可能并不是真正必要的。

    您可以使用 filterforEachmap 等以更少的代码完成此操作,但通常普通循环比嵌套迭代器运行得更快:

      function filterOn(data, value) {
        var re = new RegExp(value,'i');
        var result = [];
        var details, keys, obj, temp;
    
        for (var i=0, iLen=data.length; i<iLen; i++) {
          temp = {level: data[i].level, details:[]};
          details = data[i].details;
    
          for (var j=0, jLen=details.length; j<jLen; j++) {
            obj = details[j];
    
            for (var p in obj) {
    
              if (obj.hasOwnProperty(p) && re.test(obj[p])) {
                temp.details.push(details[j]);
                break;
              }
            }
          }
          if (temp.details.length) result.push(temp);
        }
        return result;
      }
    

    【讨论】:

    • 为什么要中断第三个 for 循环?
    猜你喜欢
    • 2017-06-14
    • 2022-01-08
    • 2019-01-24
    • 1970-01-01
    • 2022-01-12
    • 2021-09-14
    • 2015-03-24
    • 1970-01-01
    相关资源
    最近更新 更多