按属性订购元素

时间:2018-08-23 11:19:37

标签: javascript jquery

我有一个项目列表和两个数组:

  • favouriteItems
  • blockedItems

我想通过以下方式对商品重新排序:

  • 仅限“收藏夹”
  • 不是“收藏夹”,不是“阻止”
  • 仅“被阻止”

我的脚本的问题是“被阻止”的项目高于“未标记”的项目。

那里怎么了?

var favouriteItems = [2];
var blockedItems = [1, 3];

function isFavourite(id) {
  return (favouriteItems.includes(id));
}

function isBlocked(id) {
  return (blockedItems.includes(id));
}

function isNotMarked(id) {
  return ((!isFavourite(id) && (!isBlocked(id))));
}

$("div.container div.item").sort(function(a, b) {
  var aId = $(a).data("id");
  var bId = $(b).data("id");

  // check favourites
  if ((isFavourite(aId)) && (!isFavourite(bId)))
    return 1;

  if ((isFavourite(bId)) && (!isFavourite(aId)))
    return -1;

  if ((isFavourite(aId)) === (isFavourite(bId)))
    return 0;

  // check blocked
  if ((isBlocked(aId)) && (!isBlocked(bId)))
    return -1;

  if ((isBlocked(bId)) && (!isBlocked(aId)))
    return 1;

  if ((isBlocked(aId)) === (isBlocked(bId)))
    return 0;

  // both are not marked
  return 0;

}).appendTo("div.container");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="item" data-id=1>Banana B</div>
  <div class="item" data-id=2>Carrot F</div>
  <div class="item" data-id=3>Orange B</div>
  <div class="item" data-id=4>Apple</div>
  <div class="item" data-id=5>Carrot</div>
</div>

3 个答案:

答案 0 :(得分:3)

以下是代码中需要解决的问题和改进的列表

  • check blocked部分和后续的return从未执行过,因为该函数在此之前返回,因为它涵盖了2个变量之间的所有4个相等情况。
  • 如果顺序与要求相同,则返回-1并交换返回1。因此,当a收藏夹b不是时,返回-1。同样,当a阻止b没有被阻止时,返回1。
  • ab既是收藏夹还是都不是收藏夹时,让代码检查是否ab被阻止,然后最后返回{ {1}}(不变)
  • 有一个未使用的功能0,应将其删除

您可以按以下方式简化排序逻辑。

isNotMarked
var favouriteItems = [2];
var blockedItems = [1, 3];

function isFavourite(id) {
  return (favouriteItems.includes(id));
}

function isBlocked(id) {
  return (blockedItems.includes(id));
}

$("div.container div.item").sort(function(a, b) {
  var aId = $(a).data("id");
  var bId = $(b).data("id");

  return isFavourite(bId) - isFavourite(aId) || isBlocked(aId) - isBlocked(bId);

}).appendTo("div.container");

此外,您可以按照以下相同的编码样式来纠正逻辑。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="item" data-id=1>Banana B</div>
  <div class="item" data-id=2>Carrot F</div>
  <div class="item" data-id=3>Orange B</div>
  <div class="item" data-id=4>Apple</div>
  <div class="item" data-id=5>Carrot</div>
</div>
var favouriteItems = [2];
var blockedItems = [1, 3];

function isFavourite(id) {
  return (favouriteItems.includes(id));
}

function isBlocked(id) {
  return (blockedItems.includes(id));
}

$("div.container div.item").sort(function(a, b) {
  var aId = $(a).data("id");
  var bId = $(b).data("id");

  // check favourites
  if ((isFavourite(aId)) && (!isFavourite(bId)))
    return -1;

  if ((isFavourite(bId)) && (!isFavourite(aId)))
    return 1;

  // check blocked
  if ((isBlocked(aId)) && (!isBlocked(bId)))
    return 1;

  if ((isBlocked(bId)) && (!isBlocked(aId)))
    return 0;


  // both are not marked
  return 0;

}).appendTo("div.container");

供参考,Array.sort

答案 1 :(得分:0)

在我看来,您好像在对物品进行错误的分类!

如果f(a,b)b之前,则排序函数a应该返回1。 在您的解决方案中,正好相反

 if ((isFavourite(aId)) && (!isFavourite(bId)))
     return 1;

如果a是收藏夹,而b不是收藏夹,那么a应该在b之前。而返回1表示b早于a

请参见docs

答案 2 :(得分:0)

编写排序函数的方式将永远不会执行“检查块”之后的代码,因为该函数必定会在三个第一个返回值之一处结束。

如果您编写一个用于将价值归因于考虑所有条件的项目的函数,然后使用它对它们进行排序,它将起作用:

var favouriteItems = [2];
var blockedItems = [1, 3];

function isFavourite(id) {
  return (favouriteItems.includes(id));
}

function isBlocked(id) {
  return (blockedItems.includes(id));
}

function isNotMarked(id) {
  return ((!isFavourite(id) && (!isBlocked(id))));
}

function sortValue(id) {
  var sortValue = 0;
  if (isFavourite(id)) sortValue += 2;
  if (isNotMarked(id)) sortValue += 1;
  
  return sortValue;
}

$("div.container div.item").sort(function(a, b) {
  var aId = $(a).data("id");
  var bId = $(b).data("id");
  
  return sortValue(bId) - sortValue(aId);
}).appendTo("div.container");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="item" data-id=1>Banana B</div>
  <div class="item" data-id=2>Carrot F</div>
  <div class="item" data-id=3>Orange B</div>
  <div class="item" data-id=4>Apple</div>
  <div class="item" data-id=5>Carrot</div>
</div>