【问题标题】:Structure order of an array based on an item in the array has certain value set to true基于数组中某项的数组的结构顺序将某个值设置为true
【发布时间】:2020-02-12 14:30:06
【问题描述】:

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

问题是来自 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
            }
        }
    }

【问题讨论】:

    标签: javascript arrays reactjs typescript gatsby


    【解决方案1】:

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

    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 函数以考虑具有不同长度的数组并确定要循环的数组(可能是两者之间的最大长度)。

    【讨论】:

    • 这可行。但正如我所说,我确实需要至少两个falsyValueszippedValues 数组中彼此相邻。它可能超过两个,但它们需要成对出现。示例[truthy, falsy, falsy, truthy, falsy, falsy, falsy, falsy,truhty]
    • @MattiasRådemar 我刚刚编辑了它,试试类似的东西。我还没有测试它,所以你必须稍微调整一下。此外,您很可能需要包含一些更悲伤的路径条件。
    • 是的,您编辑的解决方案似乎大部分都可以解决问题。只需要更改它,如果它位于底部,我可以获得一个 falsyValue。谢谢老哥!
    • @MattiasRådemar 没问题,希望它能让你到达你想去的地方!
    猜你喜欢
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多