循环到嵌套数组并修改数据

时间:2019-08-02 08:09:43

标签: javascript arrays multidimensional-array

根据上述结构,所有类型都具有text-1

我只希望第一个出现在text-1中,其余所有都应该属于text-2中的data structure

并且不应更改块的顺序。同样,block可以具有不应该受到影响的不同类型。

我试图循环每个块,但没有修改仅第一次出现的逻辑。请帮助

下面是我到目前为止所尝试的,

let newData = data.forEach(data => {
  return data.block.forEach(block => {
    return block.child.forEach((type, i) => {
      if (i === 0) { return }
      type.type = 'text-2'
    })
  });
});

当前数据

const data = [
  {
    block: [
      { child: [{ type: 'text-1' }] },
      { child: [{ type: 'any type' }] },
      { child: [{ type: 'text-1' }] }
    ]
  },
  {
    block: [
      { child: [{ type: 'text-1' }] },
      { child: [{ type: 'text-1' }] }
    ]
  }
]

预期数据

const data = [
  {
    block: [
      { child: [{ type: 'text-1' }] },
      { child: [{ type: 'any type' }] },
      { child: [{ type: 'text-2' }] }
    ]
  },
  {
    block: [
      { child: [{ type: 'text-2' }] },
      { child: [{ type: 'text-2' }] }
    ]
  }
]

3 个答案:

答案 0 :(得分:2)

您可以通过获取一次获取第一个字符串,并针对所有其他调用另一个字符串的函数来映射项和嵌套项。

const
    getOnce = (first, other, used) => () => used ? other : (used = true, first);
    data = [{ block: [{ child: [{ type: 'text-1' }] }, { child: [{ type: 'any type' }] }, { child: [{ type: 'text-1' }] }] }, { block: [{ child: [{ type: 'text-1' }] }, { child: [{ type: 'text-1' }] }] }],
    type1 = 'text-1',
    type2 = 'text-2',
    getType = getOnce(type1, type2),
    result = data.map(
        ({ block }) => ({
            block: block.map(
                ({ child }) => ({
                    child: child.map(o => Object.assign({}, o, o.type === type1 && { type: getType() }))
                })
            )
        })
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)

使用JSON.parse revival parameter的通用替代方法:

var found = 0, data = [{ block: [{ child: [{ type: 'text-1' }] }, { child: [{ type: 'any type' }] }, { child: [{ type: 'text-1' }] }] }, { block: [{ child: [{ type: 'text-1' }] }, { child: [{ type: 'text-1' }] }] }]

data = JSON.parse(JSON.stringify(data), 
              (key, val) => key == 'type' && val == 'text-1' && found++ ? 'text-2' : val)

console.log( data )


使用for...of替换替代项:

const data = [{ block: [{ child: [{ type: 'text-1' }] }, { child: [{ type: 'any type' }] }, { child: [{ type: 'text-1' }] }] }, { block: [{ child: [{ type: 'text-1' }] }, { child: [{ type: 'text-1' }] }] }];
let found = 0;

for (const item of data)
  for (const block of item.block)
    for (const child of block.child)
      if (child.type === 'text-1' && found++)
        child.type = 'text-2';

console.log( data );

答案 2 :(得分:0)

假设:

  • 数组结构是示例中显示的结构。
  • 每个data元素都是一个对象。
    • 每个对象都有一个block属性,它是一个数组。
    • 每个可能的块元素都具有type属性。
  • 您想更改原始数组而不复制它的新副本(这是我从问题中了解的内容,但是我当然是错的)。

这是一个(丑陋的)解决方案,可以根据需要更改值。

请注意,这种更改很奇怪,而且似乎没有什么意义,我高度建议您考虑使用替代数据结构。

代码说明直接在下面的代码中。

const data = [
  {
    block: [
      { child: [{ type: 'text-1' }] },
      { child: [{ type: 'any type' }] },
      { child: [{ type: 'text-1' }] }
    ]
  },
  {
    block: [
      { child: [{ type: 'text-1' }] },
      { child: [{ type: 'text-1' }] }
    ]
  }
];

// That's unreasonable.. anyway.
data.forEach((o, i) => {
  // loop each element, keep track of the index.
  if (i > 0) {
    // if it's NOT the first element, get all the elements who actually have a child, loop the child and for each type property, replace 1 with 2.
    o.block.forEach(c => c.child && c.child.forEach(child => child.type = child.type.replace("1","2")));
  }
  else {
    // otherwise, if that's the first element, just find the last block that has a child and whose child equals 'text-1'.
    const elems = o.block.filter(c => c.child && c.child.length && c.child.some(child => child.type === 'text-1'));
    const found = elems && elems.length && elems[elems.length - 1];
    // if found, replace the value.
    if (found) found.child[0].type = found.child[0].type.replace("1","2");
  }
});

console.log(data);