【问题标题】:Lodash: slice array and keep a specific itemLodash:切片数组并保留特定项目
【发布时间】:2016-05-27 15:46:18
【问题描述】:

我有一个从 API 获得的对象数组,其中 1 个对象具有“选定”属性。我需要将该数组切片为只有 3 个对象,并且其中 1 个对象需要是“选定”对象。我在角度应用程序中使用 lodash,但我不限于如何实现这一点,尽管我更喜欢使用 lodash 的答案。在此先感谢...请参见下面的示例:

//Sample array
var fruits = [{
  id: 1,
  fruit: "apple",
  selected: false
}, {
  id: 2,
  fruit: "pear",
  selected: false
}, {
  id: 3,
  fruit: "orange",
  selected: false
}, {
  id: 4,
  fruit: "pineaple",
  selected: false
}, {
  id: 5,
  fruit: "mango",
  selected: true
}, {
  id: 6,
  fruit: "peach",
  selected: false
}, {
  id: 7,
  fruit: "strawberry",
  selected: false
}];

预期结果:

var fruits = [{
  id: 1,
  fruit: "apple",
  selected: false
}, {
  id: 2,
  fruit: "pear",
  selected: false
}, {
  id: 5,
  fruit: "mango",
  selected: true
}];

【问题讨论】:

  • 目前还不清楚选择其他 2 个项目所需的标准。如果它是随机的,从真正的开始,然后得到其余的。总是 3 吗?
  • 是的,其他的可以随机选择,还有一个 ID 属性,我们可以根据需要对其进行排序。我已经更新了示例。

标签: javascript arrays angularjs underscore.js lodash


【解决方案1】:

在这里做出 3 个假设,但是:

var sliced = fruits.slice(0,3);

for (var i=3; i<fruits.length; i+=1)
    if (fruits[i].selected)
        sliced[0] = fruits[i];

【讨论】:

  • 我喜欢这个,短小精悍;一个“问题”可能是,如果所选项目恰好在数组中的第二或第三,那么它不会成为我们最终得到的数组的第一个。
【解决方案2】:

从不理解 IE8 后下划线或 lodash 的吸引力。现代 JS 中提供了大量出色的便捷方法。更多关于原生 JS 数组方法的信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

    //Sample array
    var fruits = [{
      fruit: "apple",
      selected: false
    }, {
      fruit: "pear",
      selected: false
    }, {
      fruit: "orange",
      selected: false
    }, {
      fruit: "pineaple",
      selected: false
    }, {
      fruit: "mango",
      selected: true
    }, {
      fruit: "peach",
      selected: false
    }, {
      fruit: "strawberry",
      selected: false
    }];

function fruitCheck(obj){
    var isDesiredFruit = (obj.fruit === 'mango') ||
        (obj.fruit === 'peach') ||
        (obj.fruit === 'strawberry');
    return isDesiredFruit;
}

var filteredFruits = fruits.filter(fruitCheck);

【讨论】:

    【解决方案3】:

    试一试:

    function getThreeFruits (fruits) {
      var split = _.partition(fruits, { selected: true })
      var selectedFruit = split[0]
      var twoOtherFruits = split[1].slice(0, 2)
      return selectedFruit.concat(twoOtherFruits)
    }
    

    【讨论】:

    • 这很棒,它按预期工作但是我决定使用 .reduce 来代替...结束了这个return user.userStoreAccesses .reduce(function(arr, el) { if (el.defaultStore) { return [el].concat(arr).slice(0, 3); } if (arr.length &gt; 2) { return arr; } arr.push(el); return arr; }, []);
    • 写完评论后,我回去决定尝试不同的方式......这是我的最后一次迭代return _(user.userStoreAccesses) .chain() .sortBy("defaultStore") .reverse() .slice(0, 3) .value()
    【解决方案4】:

    有很多方法可以解决这个问题!这是另一个 Vanilla Javascript 版本,可根据您的实际规格随意混合和匹配。

    var fruits = [{
      fruit: "apple",
      selected: false
    }, {
      fruit: "pear",
      selected: false
    }, {
      fruit: "orange",
      selected: false
    }, {
      fruit: "pineaple",
      selected: false
    }, {
      fruit: "mango",
      selected: true
    }, {
      fruit: "peach",
      selected: false
    }, {
      fruit: "strawberry",
      selected: false
    }];
    
    var selectedFruits = fruits.reduce((result, el) => {
      if(el.selected) {
        return Array(el).concat(result).slice(0, 3);
      }
      if (result.length > 2) return result;
      result.push(el);
      return result;
    }, Array());
    
    console.log(selectedFruits);
    

    【讨论】:

    • 这太棒了!我稍微修改了一下,最后得到了return user.userStoreAccesses .reduce(function(arr, el) { if (el.defaultStore) { return [el].concat(arr).slice(0, 3); } if (arr.length &gt; 2) { return arr; } arr.push(el); return arr; }, []); 谢谢你的回复:)
    • 写完评论后,我回去决定尝试不同的方式......这是我的最终迭代返回 _(user.userStoreAccesses) .chain() .sortBy("defaultStore") 。 reverse() .slice(0, 3) .value()
    【解决方案5】:
    var z= _.sortBy(fruits,function(obj){return obj.selected})
    var result.push(z.slice(0,2));
    result.push(z[z.length-1]);
    

    【讨论】:

      【解决方案6】:

      在查看了所有答案后,我决定使用这样的东西。

      return user.userStoreAccesses
        .reduce(function(arr, el) {
          //check if current obj is the defaultStore
          if (el.defaultStore) {
            return [el].concat(arr).slice(0, 3);
          }
          //the moment the array is greater than 2 stop execution
          if (arr.length > 2) {
            return arr;
          }
          //keep pushing items to the array until...
          arr.push(el);
          return arr;
        }, []);

      但是,我决定通过链接一些 lodash 方法(这是我的初衷)更简单一些。这是最终结果:

      return _(user.userStoreAccesses)
        .chain()
        .sortBy("defaultStore")
        .reverse()
        .slice(0, 3)
        .value();

      感谢您的回答,他们非常有帮助! 我希望我的方法对其他人也有用:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-05
        • 2020-02-22
        • 1970-01-01
        • 1970-01-01
        • 2011-02-08
        • 2021-02-19
        • 2012-11-10
        • 2021-06-28
        相关资源
        最近更新 更多