javascript - 基于数组中某项的数组的结构顺序将某个值设置为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
}
}
}
解决方案
我认为您可以这样做的一种方法是将响应过滤到单独的数组中:
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
函数以考虑具有不同长度的数组并确定要循环的数组(可能是两者之间的最大长度)。
推荐阅读
- java - 如何在优先队列中实现正确的排序算法?
- javascript - 为什么我的数据没有从这个 javascript 代码发送到 firebase?
- python - 我想通过 gmail 发送附件,使用打开的对话框模块选择文件
- python - 在 R 中使用“网状”函数运行连续 Python 脚本时出现问题
- python - 在 __init__ 中使用 **kwargs
- javascript - 将 UDP 数据从 Python 发送到 Javascript?
- mysql - 如何将 mysql SELECT 导出为 JSON,而不是转义文本?
- android - OkHttpInterceptor 从 kotlin 拦截器导航到登录片段
- resteasy - Quarkus + Panache + RestEasy Native Image 构建失败
- javascript - 如何在 JavaScript 中动态填充多维数组?