首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在javascript中创建一个包含2种数据类型的块函数

如何在javascript中创建一个包含2种数据类型的块函数
EN

Stack Overflow用户
提问于 2022-08-08 12:15:16
回答 2查看 133关注 0票数 1

有一个包含数据的数组:

代码语言:javascript
复制
const array = [...data]

我们必须要有数据类型:

代码语言:javascript
复制
type string
type DataObject {
   id: number;
   title:string;
}

数组中填充了大多数类型的DataObject,但也有一些类型为字符串。

现在,我们必须分块数据,但如果类型是字符串,我们只想分块到1,否则以x数;

如果x=2,这将是我们想要的结果:

代码语言:javascript
复制
const chunkedArray = [["title"], [dataObject, dataObject], [dataObject, dataObject], ["title2"]]

我就是不能把这事当回事。每次我认为我找到了解决方案,我就会得到不同的结果。这就是我现在拥有的:

代码语言:javascript
复制
const sliced = newArray.slice(i, i + numColumns);
const titleIndex = sliced.findIndex((a) => typeof a === "string");
if (titleIndex >= 0) {
  // Meaning has title
  console.log({ titleIndex, i });
  for (let a = 0; a < numColumns; a++) {
    if (a === titleIndex) {
      chunks.push([sliced[a] as any]);
    } else {
      chunks.push([sliced[a] as any]);
    }
  }
} else {
  chunks.push(sliced);
}

i += numColumns;

我得到的是:

我认为现在的问题是,我们正在循环每2次(x=2),我们需要从下一次迭代中将其添加到数组中,但我不知道如何做到这样才能工作。

如果是x=2,但如果x=3或x=4等,则不能这样做:

代码语言:javascript
复制
while (i < n) {
  const sliced = newArray.slice(i, i + numColumns);
  const titleIndex = sliced.findIndex((a) => typeof a === "string");
  if (titleIndex >= 0) {
    // Meaning has title
    for (let a = 0; a < numColumns; a++) {
      if (a === titleIndex) {
        chunks.push([sliced[a] as any]);
        i += 1;
      } else if (a === numColumns - 1) {
        chunks.push([sliced[a] as any, ...newArray.slice(i + a, i + a + 1)]);
        i += numColumns + 1;
      } else {
        chunks.push([sliced[a] as any]);
        i += 1;
      }
    }
  } else {
    chunks.push(sliced);
    i += numColumns;
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-08 13:04:08

我们可以通过将对象存储到缓存数组中来做到这一点,每次输出被填充时,我们都会将该数组推入输出中。

当我们完成迭代时,如果缓存仍然有任何对象(来自不完全组),则将其推送到输出。

看看这个:

第一部分是设置输入数据,我们关心的是splitChunks()

代码语言:javascript
复制
let strings = Array(10).fill('title');
let objects = Array.from({ length: 30 }, () => ({ title: 'title', id: 'id' }));
function shuffle(arr1, arr2) {
  if (!arr1.length || !arr2.length) return [...arr1, ...arr2];
  return Math.random() > 0.5
    ? [arr1[0], ...shuffle(arr1.slice(1), arr2)]
    : [arr2[0], ...shuffle(arr1, arr2.slice(1))];
}
const data = shuffle(objects, strings);
console.log('Data: ', data);


function splitChunks(data, groupSize) {
  let cache = [];
  const chunks = data.reduce((acc, val) => {
    if (val.title) {
      cache.push(val);
      if (cache.length === groupSize) {
        acc.push(cache);
        cache = [];
      }
    } else {
      acc.push(val);
    }
    return acc;
  }, []);

  if (cache.length) {
    chunks.push(cache);
  }
  return chunks;
}

let chunks = splitChunks(data, 4);
console.log('Chunks:', chunks);

这种方法可以扩展到更多的数据类型,方法是为每个数据类型添加一个缓存,并在还原器中添加类似的检查。

票数 0
EN

Stack Overflow用户

发布于 2022-08-08 13:31:23

您用typescript标记标记了您的问题,所以我只能假设类型对您的程序很重要。

考虑以下的职能办法:

chunkByCount函数中,创建一个result数组作为结果,并为每个对象块创建一个chunk数组。

输入数组的每个元素在循环中一次处理一个:

如果值是字符串:(如果每个字符串指示分块应该重新启动-那么当前块将被推入数组中,如果它有任何对象,并且为下一个组分配一个新的数组给chunk变量)。将字符串值放入数组中,然后将该数组推入结果数组。

如果该值不是字符串:那么它就是您的DataObject对象之一。

当遇到对象时,它会被推入chunk变量的当前数组中。如果(将当前对象推入块后)块的长度等于所需的计数,则将块数组本身推入结果数组,并创建一个新的数组并分配给chunk变量。循环结束后,如果chunk数组中有任何剩余的对象,那么这个块也会被推入结果数组。

TS游乐场

代码语言:javascript
复制
type UnchunkedArray<T> = (string | T)[];
type ChunkedArray<T> = ([string] | T[])[];

type DataObject = {
  id: number;
  title:string;
};

// Generate input array test data:
function createUnchunkedArray ({
  groups = 3,
  minGroupLength = 7,
  maxGroupLength = 10,
} = {}): UnchunkedArray<DataObject> {
  let id = 0;
  const array: UnchunkedArray<DataObject> = [];

  for (let group = 0; group < groups; group += 1) {
    array.push(`group ${group}`);

    const groupLength = Math.floor(
      Math.random()
      * (maxGroupLength - minGroupLength + 1)
    ) + minGroupLength;

    for (let i = 0; i < groupLength; i += 1) {
      array.push({id, title: `title ${group}-${i}`});
      id += 1;
    }
  }

  return array;
}

function chunkByCount (
  input: UnchunkedArray<DataObject>,
  count: number,
): ChunkedArray<DataObject> {
  const result: ChunkedArray<DataObject> = [];
  let chunk: DataObject[] = [];

  for (const element of input) {
    if (typeof element === 'string') {
      // If each string indicates that chunking should re-start,
      // then use the following code block here. Else, just remove it:
      if (chunk.length > 0) {
        result.push(chunk);
        chunk = [];
      }

      result.push([element]);
      continue;
    }

    chunk.push(element);

    if (chunk.length === count) {
      result.push(chunk);
      chunk = [];
    }
  }

  if (chunk.length > 0) result.push(chunk);
  return result;
}


// Usage example:

console.clear();
const input = createUnchunkedArray();
// Will be 2, 3, or 4:
const chunkCount = Math.floor(Math.random() * 3) + 2;
const chunked = chunkByCount(input, chunkCount);
console.log('Chunk count:', chunkCount);
console.log(chunked);

从TS游乐场编译的JavaScript,您可以重复运行,以看到不同的(随机)结果:

代码语言:javascript
复制
"use strict";
// Not used here, but you might find this type useful somewhere in context of the problem:
// type RepeatedTuple<N, T, Tup extends T[] = [T]> = Tup['length'] extends N
//   ? Tup
//   : RepeatedTuple<N, T, [...Tup, T]>;
// Generate input array test data:
function createUnchunkedArray({ groups = 3, minGroupLength = 7, maxGroupLength = 10, } = {}) {
    let id = 0;
    const array = [];
    for (let group = 0; group < groups; group += 1) {
        array.push(`group ${group}`);
        const groupLength = Math.floor(Math.random()
            * (maxGroupLength - minGroupLength + 1)) + minGroupLength;
        for (let i = 0; i < groupLength; i += 1) {
            array.push({ id, title: `title ${group}-${i}` });
            id += 1;
        }
    }
    return array;
}
function chunkByCount(input, count) {
    const result = [];
    let chunk = [];
    for (const element of input) {
        if (typeof element === 'string') {
            // If each string indicates that chunking should re-start,
            // then use the following code block here. Else, just remove it:
            if (chunk.length > 0) {
                result.push(chunk);
                chunk = [];
            }
            result.push([element]);
            continue;
        }
        chunk.push(element);
        if (chunk.length === count) {
            result.push(chunk);
            chunk = [];
        }
    }
    if (chunk.length > 0)
        result.push(chunk);
    return result;
}
// Usage example:
console.clear();
const input = createUnchunkedArray();
// Will be 2, 3, or 4:
const chunkCount = Math.floor(Math.random() * 3) + 2;
const chunked = chunkByCount(input, chunkCount);
console.log('Chunk count:', chunkCount);
console.log(chunked);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73277736

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档