【问题标题】:How to filter elements from an array until specific string如何从数组中过滤元素直到特定字符串
【发布时间】:2017-08-20 14:25:23
【问题描述】:

我正在尝试从数组中过滤出元素,直到一个特定的字符串,在这种情况下是我通过这个变量获得的日期名称(周一、周二、周三等):

var day = new Date(reservation.startDate);

我有一个元素数组,我正在使用push() 方法将它们添加到数组中。

这是数组:

console.log(JSON.stringify(arrayData, null, 4))

[
    "<b>Mon</b>",
    "<b>AUT14</b>",
    "<b>KL25AB55200-3001</b>",
    "<b>Mon</b>",
    "<b>AUT15</b>",
    "<b>KC23DK20010-3003</b>",
    "<b>Tue</b>",
    "<b>TI14</b>",
    "<b>KL04BT10110-3001</b>",
    "<b>Tue</b>",
    "<b>AUT15</b>",
    "<b>KL25AB10451-3001</b>",
    "<b>Tue</b>",
    "<b>AUT13</b>",
    "<b>AUT13</b>",
    "<b>KL25AD10000-14</b>",
    "<b>Tue</b>",
    "<b>ASR14</b>",
    "<b>Wed</b>",
    "<b>TI14</b>",
    "<b>IPS16</b>",
    "<b>A800BD65-3001</b>",
    "<b>Wed</b>",
    "<b>TI14</b>",
    "<b>KL04BT10110-3001</b>",
    "<b>Wed</b>",
    "<b>AUT15</b>",
    "<b>KL25AB55200-3002</b>",
    "<b>Thu</b>",
    "<b>AUT16</b>",
    "<b>KL25AB10250-3001</b>",
    "<b>Thu</b>",
    "<b>TI14</b>",
    "<b>IPS16</b>",
    "<b>A800BD65-3001</b>",
    "<b>Thu</b>",
    "<b>TI13</b>",
    "<b>TI14</b>",
    "<b>KL25AB10300-3001</b>"        
]

如果我想打印出 only 包含“Mon”的数据,我使用:

if (day.toString().indexOf("Mon") >= 0) {                             
    document.getElementById("Monday").innerHTML = arrayData.join("");
}

但是,例如,如果我在星期三使用相同的方法,我会从 星期一星期二 到星期三获得数据,这并不理想,因为我只想要周三的数据。

if (day.toString().indexOf("Wed") >= 0) {                                                                     
    document.getElementById("Wednesday").innerHTML = arrayData.join("");
}

那么有没有一种有效的方法来从数组中间挑选数据而不包括其他日子?

我必须使用核心 JavaScript,所以不能使用任何框架。

澄清

我需要将每天的数据打印到它们自己的innerHTML 部分中。

所以我需要("Monday").innerHTML 的这些数据:

"<b>Mon</b>",
"<b>AUT14</b>",
"<b>KL25AB55200-3001</b>",
"<b>Mon</b>",
"<b>AUT15</b>",
"<b>KC23DK20010-3003</b>",

("Tuesday").innerHTML:

"<b>Tue</b>",
"<b>TI14</b>",
"<b>KL04BT10110-3001</b>",
"<b>Tue</b>",
"<b>AUT15</b>",
"<b>KL25AB10451-3001</b>",
"<b>Tue</b>",
"<b>AUT13</b>",
"<b>AUT13</b>",
"<b>KL25AD10000-14</b>",
"<b>Tue</b>",
"<b>ASR14</b>",

("Wednesday").innerHTML:

"<b>Wed</b>",
"<b>TI14</b>",
"<b>KL04BT10110-3001</b>",
"<b>Wed</b>",
"<b>AUT15</b>",
"<b>KL25AB55200-3002</b>",

("Thursday").innerHTML:

"<b>Thu</b>",
"<b>AUT16</b>",
"<b>KL25AB10250-3001</b>",
"<b>Thu</b>",
"<b>TI14</b>",
"<b>IPS16</b>",
"<b>A800BD65-3001</b>",
"<b>Thu</b>",
"<b>TI13</b>",
"<b>TI14</b>",
"<b>KL25AB10300-3001</b>"

请注意数据每天都在变化,所以我是否应该过滤掉其他日期以及我不想包含在 innerHTML 中的数组中的数据? p>

【问题讨论】:

  • arrayData 的实际格式是什么?从您的示例中不清楚。您打印出的每一行是否都是一个元素,而逗号是该元素文本的一部分?还是用逗号分隔的元素和换行符不重要 - 换句话说,打印输出中的每一行是三个或有时是四个连续的数组元素?如果是后者,这似乎是一种非常尴尬的数据格式。您是否可以选择更改此格式以使其更易于使用?
  • @MichaelGeary 元素用逗号分隔
  • 你被这种格式卡住了,无法更改?真是一团糟!我认为打印输出中的行代表数组元素的逻辑分组,您想在其中选择其中一个组并根据行中的第一项执行某些操作?你如何决定小组的起点和终点?有些组中有三个元素,有些则有四个。您的某些包含日期名称的元素末尾有 &lt;br/&gt;,而其他元素则没有。在某些情况下,组中的最后一个元素缺少其 &lt;/b&gt; 结束标记。您的第一步必须是清理这些数据。
  • 顺便说一句,以备将来参考(实际上我建议用这个来编辑您的问题),最好使用console.log( JSON.stringify(arrayData,null,4) ) 来明确表示您的数据,这样人们就不会对其感到困惑实际格式。
  • @MichaelGeary 谢谢你的信息。我同意这确实是一团糟,但不幸的是,这是我必须处理的问题

标签: javascript arrays string filter element


【解决方案1】:

如果我得到你需要的,只需使用数组过滤函数并连接条件并传递“你的一天”。

var array = [
'<b>Mon</b>,<b>AUT14</b>,<b>KL25AB55200-3001</b>',
'<b>Mon</b>,<b>AUT15</b>,<b>KC23DK20010-3003</b>',
'<b>Tue</b>,<b>TI14</b>,<b>KL04BT10110-3001</b>',
'<b>Tue</b>,<b>AUT15</b>,<b>KL25AB10451-3001</b>',
'<b>Tue</b>,<b>AUT13</b>,<b>AUT14</b>,<b>KL25AD10000-14',
'<b>Wed</b>,<b>TI14</b>,<b>IPS16</b>,<b>A800BD65-3001',
'<b>Wed</b>,<b>TIT14</b>,<b>KL04BT10110-3001</b>',
'<b>Thu</b><br/>,<b>AUT16</b>,<b>KL25AB10250-3001</b>',
'<b>Thu</b><br/>,<b>TI14</b>,<b>KOR16</b>,<b>A800BD65-3001</b>'
];
function filtering(day, el) {
  return el.includes('<b>'+day+'</b>');
}
// printing all Thu
console.log(array.filter(filtering.bind(null, 'Thu')).join(''));
// printing all Wed
console.log(array.filter(filtering.bind(null, 'Wed')).join(''));

已编辑

我现在明白你的数据排列得很糟糕,而且你有很多元素,没有像控制台中显示的那样按行分组,所以这里有一个版本,以便重新排列你的数据然后执行你的操作:

var list = [
'<b>Mon</b>','<b>AUT14</b>','<b>KL25AB55200-3001</b>',
'<b>Mon</b>','<b>AUT15</b>','<b>KC23DK20010-3003</b>',
'<b>Tue</b>','<b>TI14</b>','<b>KL04BT10110-3001</b>',
'<b>Tue</b>','<b>AUT15</b>','<b>KL25AB10451-3001</b>',
'<b>Tue</b>','<b>AUT13</b>','<b>AUT14</b>','<b>KL25AD10000-14',
'<b>Wed</b>','<b>TI14</b>','<b>IPS16</b>','<b>A800BD65-3001',
'<b>Wed</b>','<b>TIT14</b>','<b>KL04BT10110-3001</b>',
'<b>Thu</b><br/>','<b>AUT16</b>','<b>KL25AB10250-3001</b>',
'<b>Thu</b><br/>','<b>TI14</b>','<b>KOR16</b>','<b>A800BD65-3001</b>'
];
const keywords = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
// starting data
// console.log(list);
//first reduce your array to a better data format
var orderedList = list.reduce(function(accumulator, currentValue, currentIndex, array) {
  if (keywords.filter(el => currentValue.indexOf(el) > -1).length > 0) {
     accumulator.push(currentValue);
  }
  else {
     accumulator[accumulator.length - 1] += currentValue;
  }
  return accumulator;
}, []);
// here the ordered data
// console.log(orderedList);

function filtering(day, el) {
  return el.includes('<b>'+day+'</b>');
}
// printing all Thu
console.log(orderedList.filter(filtering.bind(null, 'Thu')).join(''));
// printing all Wed
console.log(orderedList.filter(filtering.bind(null, 'Wed')).join(''));

【讨论】:

  • 所以基本上我想在他们自己的innerHTML 中获取每天的数据,例如星期四我可以使用document.getElementById("Thursday").innerHTML = array.filter(filtering.bind(null, 'Thu')); 吗?
  • 这在我将日期名称输入每个 innerHTML 的部分上运行良好,但是否可以获取其他数据以及日期名称,例如星期一:&lt;b&gt;Mon&lt;/b&gt;,&lt;b&gt;AUT14&lt;/b&gt;,&lt;b&gt;KL25AB55200-3001&lt;/b&gt;
  • 嗨@IlariM,第一个问题是的。第二个问题对不起,我没明白你的意思。请你给我解释一下好吗?
  • @quirimmo 您使用的数据格式与 OP 的数据格式不同。请参阅问题下的评论讨论。每个逗号分隔一个单独的数组元素!真是一团糟。
  • @quirimmo 在问题中更新
【解决方案2】:

如果你给元素添加一个类和一个数据属性可能会更容易:

HTML

<div class="day" data-name="Monday"></div>
<div class="day" data-name="Tuesday"></div>
<div class="day" data-name="Wednesday"></div>
<div class="day" data-name="Thursday"></div>

然后您可以使用document.querySelectorAll 一次提取所有元素:

var days = document.querySelectorAll('.day');

然后遍历每个元素,将data-name 属性作为id,检查它与数组元素的子字符串,过滤掉匹配的那些,然后将帽子HTML 添加到元素。

days.forEach(day => {
  const id = day.getAttribute('data-name').substr(0, 3);

  // Remember that in a couple of cases the filter is going to
  // return an array of two or more elements (Tuesday for example)
  // so you need to `join` those elements up
  const html = array.filter(str => str.substr(3, 3) === id).join('');
  day.innerHTML = html;
});

DEMO - 请记住,您的数组 HTML 字符串中有 &lt;br/&gt;,这就是输出有点不稳定的原因。

编辑

使用您的数据,我想出了一个解决方案来获得某种体面的输出。我会把它留在这里以防它看起来有用:

document.querySelectorAll('.day').forEach(day => {

  // Get the day name and the id (short day name)
  const label = day.getAttribute('data-name');
  const id = label.substr(0, 3);

  // Grab the relevant HTML
  const htmlArr = array.filter(str => str.substr(3, 3) === id);

  // Iterate over the filtered HTML array
  const rows = htmlArr.map(el => {

    // Split the HTML row into components
    const html = el.split(',');

    // Extract what I've called the ID and the CODE
    const id = html[1].match(/>([A-Z0-9]*)</)[1];
    const code = html[2].substr(3, 16);

    // Return that information as HTML in a template
    return `<span>${id} | ${code}</span>`;

  // For each row in the filter array, join the the returned HTML
  // with a <br/>
  }).join('<br/>');

  // Finally, use our label, and add the rows
  day.innerHTML = `<b>${label}</b><br/>${rows}`;
});

你就这样结束了:

Monday
AUT14 | KL25AB55200-3001
AUT15 | KC23DK20010-3003

Tuesday
TI14 | KL04BT10110-3001
AUT15 | KL25AB10451-3001
AUT13 | AUT14

Wednesday
TI14 | IPS16
TIT14 | KL04BT10110-3001

Thursday
AUT16 | KL25AB10250-3001
TI14 | KOR16

DEMO

【讨论】:

    猜你喜欢
    • 2021-11-11
    • 2021-02-11
    • 1970-01-01
    • 2011-11-12
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 2022-09-28
    • 2019-10-26
    相关资源
    最近更新 更多