首页 > 解决方案 > 基于数组中某项的数组的结构顺序将某个值设置为true

问题描述

我有来自我的 CMS 的传入数据,这些数据都包含 value featuredProject,它可以是 true、null 或 false。如果是真的,我会添加一个 CSS 类,使其跨越屏幕。featuredProject为了帮助保持我的网格结构完好无损,我需要在设置为 true 的项目之前或之后始终设置至少两个设置为 false 或 null 的项目featuredProject

问题是来自 CMS 的数据不尊重网格的假定设计,并且可能而且可能会从我需要正确循环出来的数据中扭曲出来。

我现在一直试图实现的是一个函数,它从 CMS 循环遍历数组中的所有项目,并查看featuredProject循环中当前项目的值。如果它设置为 true,我会回顾数组的过去 2 个索引,看看它们的featuredProject值是多少。如果它们都没有将值设置为 false 或 null 我想通过将当前索引向前移动一步来对数组进行排序,退出循环然后再次循环以检查所有值是否按顺序排列。

现在我收到一个错误,其中数组的一个值是undefined我真的不明白为什么。

显示我想要实现的网格的图像。 https://imgur.com/a/KrdwlNI

我现在拥有的代码。

移动索引的函数

function move(array: any[], from: number, to: number) {
    if (to === from) return array

    const target = array[from]
    const increment = to < from ? -1 : 1

    for (let k = from; k != to; k += increment) {
        array[k] = array[k + increment]
    }
    array[to] = target
    return array
}

检查值的函数featuredProject

const sortImageGrid = (arr: any[]): any[] => {
    // console.log(arr)

    const sortedArr: any[] = []
    arr.map((item, index) => {
        if (item === undefined) {
            return
        }
        // console.log(item)
        if (index === 0) {
            sortedArr.push(item)
        } else if (index === 1 && item.featuredProject) {
            move(arr, index, index + 1)
        } else if (index === 1 && !item.featuredProject) {
            sortedArr.push(item)
        } else if (
            item.featuredProject &&
            !arr[index - 1].featuredProject &&
            !arr[index - 2].featuredProject
        ) {
            sortedArr.push(item)
        } else if (
            (item.featuredProject && arr[index - 1].featuredProject === true) ||
            (item.featuredProject && arr[index - 2].featuredProject === true)
        ) {
            move(arr, index, index + 1)
        } else {
            sortedArr.push(item)
        }
        console.log(sortedArr)
    })
    if (sortedArr.length === arr.length) {
        return sortedArr
    } else {
        return []
    }
}

我如何在绘制项目的组件中运行该函数

    const [gridSorted, setGridSorted] = useState(false)
    let sortedArr: any[] = []

    if (data.allSanityProject.nodes && data.allSanityProject.nodes.length > 0) {
        while (gridSorted === false) {
            sortedArr = sortImageGrid(data.allSanityProject.nodes)
            // console.log(sortedArr)
            if (sortedArr.length === data.allSanityProject.nodes.length) {
                setGridSorted(true)
                return
            }
        }
    }

标签: javascriptarraysreactjstypescriptgatsby

解决方案


我认为您可以这样做的一种方法是将响应过滤到单独的数组中:

let falsyValues = [];
let truthyValues = []
for(let item of arr){
    if(item.featuredProject){
        truthyValues.push(item)
    } else {
        falsyValues.push(item)
    }
}

然后创建一个根据您的标准“压缩”它们的函数:

function zip(falsyArr, truthyArr){
    let zippedValues = []
    for(let i = 0, n = 0; i < falsyArr.length; i++, n += 2){
        if(!falsyArr[n] || !falsyArr[n+1]){
            return zippedValues
        }
        zippedValues.push(falsyArr[n], falsyArry[n+1], truthyArr[i])
    }
    return zippedValues;
}

您只需稍微调整zip函数以考虑具有不同长度的数组并确定要循环的数组(可能是两者之间的最大长度)。


推荐阅读