js 数组排序 元素定位

有数组

var arr = [
        {id: 0, name: 1}, 
        {id: 1, name: 2},
        {id: 2, name: 3},
        ...]

共20条数据,
循环数组 给每项加left,top属性,
循环出下图,每行最多10个数据,元素从中间往两边展开,
数据可混排

image.png

阅读 3.2k
5 个回答
const arr = Array.from({ length: 20 }, (_, i) => ({ id: i, name: i + 1 }));

/** Max items length per line */
const SIZE = 10;

/** Geometric attributes (in pixel) of each item */
const ITEM_WIDTH = 60;
const ITEM_HEIGHT = 24;
const GUTTER_H = 8;
const GUTTER_V = 8;
const ROWS_OFFSET_X = [0, ITEM_WIDTH / 2];

/** Sort and group items */
const rows = Array.from({ length: Math.ceil(arr.length / SIZE) }, () => []);
for (let n = rows.length, i = 0, item = arr[i]; item; item = arr[i += 1]) {
    rows[i % n][Math.random() < 0.5 ? "push" : "unshift"](item);
}

/** Calculate geometric attributes of each item */
for (let i = 0, row = rows[i]; row; row = rows[i += 1]) {
    const top = (ITEM_HEIGHT + GUTTER_V) * i;
    for (let j = 0, item = row[j]; item; item = row[j += 1]) {
        const left = (ITEM_WIDTH + GUTTER_H) * j + ROWS_OFFSET_X[i];
        Object.assign(item, { left, top });
    }
}

console.log(arr);

先写前面,我有个问题,20不应该在最左边吗?


function(arr:number[]){
    let a =[]
    let b =[]
    let c =[]
    let d =[]
arr.forEach(e=>{
    let k = math.floor(e/2)
   if(e==k){
        if(k%2==1){
            a.push(e)
        }else{
            b.push(e)
        }
    }else{
        if(k%2==1){
            c.push(e)
        }else{
            d.push(e)
        }

    }
})

    return [
        [...a, ...b.reverse()],
        [...c, ...d.reverse()]
]
}

手机打的,你跑着试试?

你这个写算法的话很复杂,如果只有20个不如直接写。

var template = [[17,13,9,5,1,3,7,11,15,19], [16,12,6,2,4,8,10,14,18,20]];
template.map(row => <div>
    row.map(itemIndex => arr[item.index] && <div> arr[item.index] </div>);
</div>);

边距什么的属于css问题,调就行了。

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

尝试了一下,没找到布局规律

const arr = Array.from(Array(20), (_, i) => i + 1);

function place(list) {
    const lines = [[], []];
    const actions = [
        Array.prototype.unshift,
        Array.prototype.unshift,
        Array.prototype.push,
        Array.prototype.push,
    ];

    list.forEach((el, i) => {
        const action = actions[i % actions.length];
        const line = lines[i % 2];
        action.call(line, el);
    });

    return lines;
}

console.log(place(arr));

输出和题中的图片有一些出入

[
    [ 17, 13, 9, 5, 1, 3, 7, 11, 15, 19 ],
    [ 18, 14, 10, 6, 2, 4, 8, 12, 16, 20 ]
]

布局完了之后,根据这个布局数组来设计 left 和 top 就可以了。

看下图,有些长箭头没画,但可以看出来,这个布局到 9 之后就找不到规律了

image.png


虽然布局不一致,还是把代码补完吧,接上面的

function layout(rows, { width, space, height }) {
    const step = width + space;
    return rows
        .flatMap((row, rowIndex) => {
            const leftOffset = (width / 2 | 0) * (rowIndex % 2);
            const top = rowIndex * height;
            return row.map((name, i) => ({
                id: name - 1,
                name,
                left: leftOffset + step * i,
                top
            }));
        })
        .sort((a, b) => a.id - b.id);
}

// 调用示例
console.log(layout(place(arr), { width: 64, space: 4, height: 32 }));

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题