微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将数组转换为多个数组 使用 While 循环的解决方案使用正则表达式的解决方案

如何解决将数组转换为多个数组 使用 While 循环的解决方案使用正则表达式的解决方案

我正在尝试操作一个数组,但似乎无法将其转换成我想要的形式。

这是数组:

const children = [
  { type: 'span' },{ type: 'br' },{ type: 'span' },]

所以挑战是创建一个数组数组。每当有 2 个或更多连续的 br 值时,这表示一个数组的结束位置和下一个数组的开始位置。所以我试图做到这一点:

[
  [{type: 'span'},{type: 'br'},{type: 'span'}],[{type: 'span'}],[{type: 'span'},{type: 'span'}]
]

注意可以有任意数量的连续 br 标签

想知道 reduce 是否比 forEach 更好?

解决方法

它有点懒,你可能想根据你的数据选择 \n 以外的分隔符,但是

const children = [
  'span','br','span','span'
]

console.log(children.join("\n").split(/(?:\nbr){2,}\n/).map(p => p.split("\n")))

当然有效...

,
console.log(
  children
  .map(({ type: t }) => t) // to array of strings
  .map(t => t === 'br' ? ' ' : t) // br => ' ' for using split() and trim()
  .join('') // to long string,.split('  ') // split by 2 'br'
  .map(r => r.trim()) // remove leading & trailing 'br's 
  .map(r => r
    .replace(' ','|br|') // restore 'br'
    .split('|') // split to array
    .map(r => ({type : r})) // restore structure
    )
  );
,

我不是 100% 确定这有效,我觉得它可以更简洁一些,但这里尝试使用 reduce:

const children = [{"type":"span"},{"type":"br"},{"type":"span"},{"type":"span"}];

const is_br = (item) => item?.type === 'br';

const result = children.reduce(
  (acc,val,i,{ [i - 1]: prev,[i + 1]: next }) => {
    if(!is_br(prev) && is_br(val) && is_br(next))
      acc.push([]);
  
    if(is_br(val) && (is_br(prev) || is_br(next)))
      return acc;
    
    acc[acc.length - 1].push(val);
    
    return acc;
  },[[]]
);

console.log(result);

您的代码的可能工作(或接近)版本:

const children = [{"type":"span"},{"type":"span"}];

let paragraphs = []
let elements = []
let flag = false
children.forEach((child,idx) => {
  if (child.type !== 'br') {
    flag = false
    elements.push(child)
  } else {
    if (flag) {
      if(elements.length > 1) {
        paragraphs.push(elements.splice(0,elements.length - 1))
      }
      elements = []
    } else {
      elements.push(child)
      flag = true
    }
  }
  
  if(idx === children.length - 1 && elements.length > 0)
    paragraphs.push(elements)
});

console.log(paragraphs);

,

使用 While 循环的解决方案。

  • 有两个变量,第一个是计数器 i,第二个是 temp,用于帮助存储不同的数组切片。

  • 接下来,有一个嵌套的 while 循环。第一个是简单的循环,第二个循环是跳过所有连续的"br"

  • 有一个 flag 来检查第二个 while 循环是否运行。

    • 如果这样做意味着我们现在需要将 temp 的内容推入结果数组 res 并清空 temp

    • 如果没有,我们需要继续推动 temp

这里还有一些检查来处理一些边缘情况。

const children = [{type:"span"},{type:"br"},{type:"span"},{type:"span"}];

const res = [];

let i = 0;
let temp = [];

while (i < children.length) {
  let flag = false;
  while (i < children.length && children[i].type === "br" && children[i + 1]?.type === "br") {
    i++;
    flag = true;
  }
  if (flag) { res.push(temp); temp = []; i++; }
  if (i >= children.length) break;
  temp.push(children[i]);
  i++;
}

if (temp.length > 0) res.push(temp);

console.log(JSON.stringify(res));

使用正则表达式的解决方案

(灵感来自 Ralkov 的解决方案)

const 
 children = [{type:"span"},{type:"span"}],res = children
  .map(({ type }) => `${type} `)
  .join("")
  .replace(/(?:br\s){2,}/g," ")
  .trim()
  .split("  ")
  .map((s) => s.split(",").map((type) => ({ type })));
  
console.log(JSON.stringify(res));

,

你可以减少数组。

const
    children = [{ type: 'span' },{ type: 'br' },{ type: 'span' },{ type: 'span' }],separator = 'br',result = children.reduce((r,o,a) => {
        if (o.type === separator) {
            if (a[i - 1]?.type === separator) {
                if (r[r.length - 1].length) r.push([]);
                return r;
            } else if (a[i + 1]?.type === separator) return r;
        }
        r[r.length - 1].push(o.type);
        return r;
    },[[]]);
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

,

这里有一个 1) 将您的对象数组转换为字符串,2) 在多个 b 上拆分和 3) 将拆分的数组转换回对象:

const children = [
  { type: "span" },{ type: "br" },{ type: "span" },];

const map = { s: "span",b: "br" };

console.log(
  children
    .reduce((s,o) => (s += o.type[0]),"")   // convert obj arr to string
    .split(/b{2,}/)                           // splits string on 2 or more 'b's
    .map((s) => {                             // convert split strings back into obj arr
      const res = [];
      for (const ch of s) {
        res.push({ type: map[ch] });
      }
      return res;
    })
);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。