【问题标题】:Count items that occur in series计算连续出现的项目
【发布时间】:2016-03-30 18:24:34
【问题描述】:

有没有办法计算连续出现的项目(连续而不中断)?假设我们有

<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 

但我知道有些不对劲(或根本不对)。

【问题讨论】:

  • 所以你想统计smalllarge类的元素个数?
  • 也许values.push(parseInt($(this).text(), 10))...
  • 我需要最近出现的那个,在这种情况下是“大”元素。它(系列中的总元素)将是 3。
  • "span .large ~ span .large" 选择作为span .large span 的一般兄弟的后代的.large 元素; html 上似乎不存在这些元素?
  • 串联表示没有中断。只有当“大”“大”“大”而不是“大”“大”“小”“大”时才是真的

标签: javascript jquery html find-occurrences


【解决方案1】:

不,那您似乎弄错了:),要求是 查找系列中元素的数量(相邻的兄弟姐妹),

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

您可以使用:has() 选择器span:has(.large) + span:has(.large) 来返回与包含.large 元素的span 相邻的兄弟元素。注意,这应该返回第一个span:has(.large)span:has(.large),不包括第一个span:has(.large)。尽管可以通过确定 span:has(.large) 元素的总数 .length 来得出准确的 .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>

【讨论】:

  • 不,该代码的工作方式如下:如果在 5 次出现中,第 5 个是大还是小,它会告诉它们是小还是大,如果它们是混合的,它会告诉系列不够长。现在我想数一数,而不是将系列分为大数或小数。
  • 是否要求 1) 检查五个 .large 元素是否是 html 中的相邻兄弟?然后如果 1) 为真,2) 检查每个元素的文本是否在给定范围内?
  • 不,那您似乎弄错了:),要求是找到系列中元素的数量(相邻兄弟姐妹),
  • “行不通”是什么意思?请注意,没有任何 .large 元素是 html.large 元素的相邻兄弟元素。
  • 第二个代码 sn-p 有效,如果您能告诉我它是如何工作的,我将不胜感激。而且,有什么方法可以找到firstLargeSetfirstSmallSet 之间的第一个?
【解决方案2】:

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

请注意,这对结构一无所知,也不强制执行。它将获取类为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 )

【讨论】:

  • Uncaught TypeError: Reduce of empty array with no initial value
  • @Klajdi - 谢谢,修改最后一行以添加初始值 0,因此在空元素数组上没有错误 - 这是否回答了您最初的问题?我创建了您的 DOM 结构,并且在测试时它可以正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 2020-05-06
  • 2015-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多