计算系列中出现的项目

Count items that occur in series

有什么方法可以计算连续出现的项目(连续不间断地)?假设我们有

<span><div class="amount large">100</div></span>
<span><div class="amount large">120</div></span>
<span><div class="amount large">300</div></span>
<span><div class="amount small">90</div></span>
<span><div class="amount large">110</div></span>
<span><div class="amount large">520</div></span>
... List continues

我确实把它们分成

function isBigEnough(element, index, array) {
  return element >= 100;
}

function isNotBigEnough(element, index, array) {
  return element <= 99;
}

var values = [];

$(".amount").slice(0, 5).each(function(index){
    values.push($(this).text());
});

if (values.every(isBigEnough)) {
    console.log("Large");
} else if (values.every(isNotBigEnough)) {
    console.log("Small");
} else {console.log("No Series")}

如何计算一行中出现了多少个元素,在我的例子中是 3 个。

我试过了

 $("span .large ~ span .large").length 

但我知道有某事不对(或根本不对)。

No, thats where you seem to be mistaken :) , the requirement is to find the number of elements in series (adjacent siblings),

在问题的 html 处,没有任何 .large 元素是 .large 元素的相邻兄弟;因为所有 .large 元素都是 span 元素的后代。参见 Adjacent sibling selectors

您可以使用 :has() 选择器 span:has(.large) + span:has(.large) 到 return 元素,这些元素是包含 .large 元素的 span 的相邻兄弟元素。请注意,这应该 return 第一个 span:has(.large)span:has(.large) 不包括第一个 span:has(.large)。虽然准确的 .length 可以通过确定 span:has(.large) 个元素的总数 .length 然后加一或乘除得到。

var adjacentLarge = $("span:has(.large) + span:has(.large)");

console.log(
  adjacentLarge.length, // this should return 3; .large having text 120, 300, 520
  $("span:has(.large)").length 
  * (adjacentLarge.length / adjacentLarge.length) // 5
); 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<span><div class="amount large">100</div></span>
<span><div class="amount large">120</div></span>
<span><div class="amount large">300</div></span>
<span><div class="amount small">90</div></span>
<span><div class="amount large">110</div></span>
<span><div class="amount large">520</div></span>


您可以使用 .filter().prev().is().nextUntil().nextAll().add().next()

var adjacentLarge = $("span:has(.large):first").filter(function() {
  return !$(this).prev().is(":has(.large)")
});

var firstLargeSet = adjacentLarge.nextUntil(":not(:has(.large))")
                    .add("span:has(.large):first");

var secondLargeSet = firstLargeSet.filter(":eq(-1)")
                     .nextAll(":has(.large)")
                     .filter(function() {
                       return $(this).next().is(":has(.large)") 
                              || $(this).prev().is(":has(.large)")
                     });

function isBigEnough(element, index, array) {
  return element >= 100;
}

function isNotBigEnough(element, index, array) {
  return element <= 99;
}

var values1 = [];

firstLargeSet.each(function(index) {
  console.log(this.textContent); // 100, 120, 300
  values1.push($(this).text());
});

if (values1.every(isBigEnough)) {
  console.log("Large"); // Large
} else if (values1.every(isNotBigEnough)) {
  console.log("Small");
} else {
  console.log("No Series")
}

var values2 = [];

secondLargeSet.each(function(index) {
  console.log(this.textContent); // 110, 520
  values2.push($(this).text());
});

if (values2.every(isBigEnough)) {
  console.log("Large"); // Large
} else if (values2.every(isNotBigEnough)) {
  console.log("Small");
} else {
  console.log("No Series")
}

var adjacentLarge = $("span:has(.large):first").filter(function() {
  return !$(this).prev().is(":has(.large)")
});

var firstLargeSet = adjacentLarge.nextUntil(":not(:has(.large))")
                    .add("span:has(.large):first");

var secondLargeSet = firstLargeSet.filter(":eq(-1)")
                     .nextAll(":has(.large)")
                     .filter(function() {
                       return $(this).next().is(":has(.large)") 
                              || $(this).prev().is(":has(.large)")
                     });

function isBigEnough(element, index, array) {
  return element >= 100;
}

function isNotBigEnough(element, index, array) {
  return element <= 99;
}

var values1 = [];

firstLargeSet.each(function(index) {
  console.log(this.textContent); // 100, 120, 300
  values1.push($(this).text());
});

if (values1.every(isBigEnough)) {
  console.log("Large"); // Large
} else if (values1.every(isNotBigEnough)) {
  console.log("Small");
} else {
  console.log("No Series")
}

var values2 = [];

secondLargeSet.each(function(index) {
  console.log(this.textContent); // 110, 520
  values2.push($(this).text());
});

if (values2.every(isBigEnough)) {
  console.log("Large"); // Large
} else if (values2.every(isNotBigEnough)) {
  console.log("Small");
} else {
  console.log("No Series")
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<span><div class="amount large">100</div></span>
<span><div class="amount large">120</div></span>
<span><div class="amount large">300</div></span>
<span><div class="amount small">90</div></span>
<span><div class="amount large">110</div></span>
<span><div class="amount large">520</div></span>

遍历元素并比较一行中的两个是否相等;如果是,则增加一个计数器。如果不是,则创建一个新计数器。最后一步取所有计数器的最大值。

请注意,这对结构一无所知,也不强制执行任何结构。它将获取 class 为 amount 的所有元素。因此,如果您想将结果缩小到 DOM.

的更具体部分,您可以修改第一行的选择器
$.makeArray($(".amount"))
  .reduce(function(pVal,cVal,i,array) {
      if (i > 0 && ((array[i-1].classList.contains("large") && array[i].classList.contains("large"))
          || (array[i-1].classList.contains("small") && array[i].classList.contains("small"))))
        pVal[pVal.length-1]++;
      else 
        pVal.push(1);
      return pVal;
   }, [] )
  .reduce( (a,b) => a > b ? a : b , 0 )