用于为materialUI生成一个随机网格的算法,该网格具有最多3列的行

时间:2019-01-30 05:38:40

标签: javascript material-ui

我正在构建一个使用reddit api和oAuth的React应用程序。

我正在使用MaterialUI,并且尝试使用Component构造一个三列图像的网格,这些图像具有动态生成的列宽值,最大显然为3。

获取的图像帖子数组中的第一项将被赋予一个介于1和3之间的随机数的键/值对。第二项将被赋予一个完成该行的数字的键/值对,如果第一项的值是!= 3。

然后,它将重新开始,其想法是每次加载网格时,它的第一项可能是1列宽,2列宽或3列宽的整行,并且算法应该完成网格的其余部分相应地表示所有行必须总计为3。

我尝试了多种方式处理帖子数组,从在循环外为数组中的前两个对象分配值,然后定义“最后一个帖子”和“该帖子之前”变量以尝试找出一种使行加起来的方法。我试图提出一套规则,无论数组的位置如何,该规则都可以使之工作,但是似乎无法得出没有几个极端情况的答案。

makeTiles() {
    let posts = this.props.posts;
    let postsWithCols = [];
    posts[0].cols = Math.floor(Math.random() * 3 + 1);
    console.log(posts[0])
    postsWithCols.push(posts[0]);
    let previousPost = postsWithCols[postsWithCols.length - 1];
    switch(previousPost.cols) {
      case 1: 
      console.log('is1');
      posts[1].cols = Math.floor(Math.random() * 2 + 1);
      postsWithCols.push(posts[1]);
      break;
      case 2: 
      console.log('is2');
      posts[1].cols = 1;
      postsWithCols.push(posts[1]);
      break;
      case 3: 
      console.log('is3');
      posts[1].cols = Math.floor(Math.random() * 3 + 1);
      postsWithCols.push(posts[1]);
      break;
      default:
      console.log('something went wrong');
      break;
    }
    let postBeforeThat = postsWithCols[postsWithCols.length - 2];
    console.log(previousPost)
    console.log(postBeforeThat)
    console.log(postsWithCols)
  }
  render() {
    this.makeTiles();
    return (
      <div>
        open grid when i can get tileData figured out.
        {/* <ImageGrid tileData={this.makeTiles()} {...this.props}/> */}
      </div>
    );
  }
}

我做过这种工作的唯一方法是,它在第​​一个初始图块之后一直在1和2之间交替显示。

2 个答案:

答案 0 :(得分:0)

这里有几个问题。首先,所提供的代码实际上只会给您两个最大值。没有循环或返回来填充更多列的事情。其次,我认为您要尝试执行的操作是创建一系列也具有列值的帖子数组,但是该方法永远不会返回最终值(postsWithCols)。我将假设您仍然只希望使用具有列值的帖子列表,而不是将其进一步拆分为行。

let posts = this.props.posts;

// Const for the max
const maxColumns = 3;

// Variable to keep track of current remaining columns. 
let remainingColumns = maxColumns;

// Go over each post and return the post with cols in to a new array. 
let postsWithCols = posts.map((post, index) => {
   // Special case, if last item, fill remaining
   if (index === posts.length - 1) {
      post.cols = remainingColumns;
      return post;
   }

   // Get a random number for the remaining columns for this row
   const cols = Math.floor(Math.random() * remainingColumns + 1);
   post.cols = cols;

   // Subtract the value
   remainingColumns = remainingColumns - cols;

   // If value is 0, reset to max. 
   if (remainingColumns <= 0) {
      remainingColumns = maxColumns;
   }

   // Add to result array
   return post;
});

console.log(postsWithCols); 

还有很多可以调整的地方,但这是总的想法。

答案 1 :(得分:0)

我最终能够解决这个问题。

      getPostsWithColumns = (posts) => {
    const postsWithColumns = posts.reduce((accum, post) => {
      const lastIndex = accum.length - 1;
      if (accum[lastIndex] && this.totalColumns(accum[lastIndex]) < 3) {
        const currentTotal = this.totalColumns(accum[lastIndex]);
        const postWithCols = {
          ...post,
          cols: currentTotal === 2 ? 1 : this.randomNumber(2)
        };
        accum[lastIndex] = [...accum[lastIndex], postWithCols];
        return accum;
      }
      const postWithCols = {
        ...post,
        cols: this.randomNumber(3)
      }
      return [...accum, [postWithCols]];
    }, []);
    return postsWithColumns.reduce((accum, group) => [...accum, ...group], []);
  };