如何排序Firebase嵌套对象数组且避免数据丢失?
问题:按likeCount排序对象并保留原结构且不丢失数据
你的问题分析
先拆解下现有代码的两个核心问题:
- 数据丢失:你用了
every方法,它的特性是只要回调返回false就会立刻终止遍历。你写的return index < 20意味着只会处理前20个条目,后面的所有数据都被直接跳过了,这就是80MB文件变成50MB的根源。 - 输出格式不符预期:
map操作把每个键值对转成了包含key字段的独立对象,然后逐个写入文件,最终得到的是零散的对象拼接(甚至不是合法的JSON结构),而非你想要的原key-value格式的对象。
正确解决方案
我们需要先按likeCount排序得到键的顺序,再重新构建排序后的对象,最后一次性写入文件(避免异步写入的顺序混乱和数据遗漏)。
步骤1:排序并构建新对象
ES6+的JavaScript对象会保留插入顺序,所以我们可以先拿到排序后的键数组,再用这些键构建新的排序对象:
const presets = { key1: { val1: "asd", val2: "dsadd", singles: { likeCount: 23 } }, key2: { val1: "asd2", val2: "dsadd2", singles: { likeCount: 100 } }, key3: { val1: "asd3", val2: "dasad3", singles: { likeCount: 15 } }, key4: { val1: "asd3", val2: "dasad3", singles: { likeCount: 80 } } }; // 1. 获取按likeCount降序排列的键数组 const sortedKeys = Object.keys(presets).sort((keyA, keyB) => { return presets[keyB].singles.likeCount - presets[keyA].singles.likeCount; }); // 2. 构建排序后的对象(两种方式可选) // 方式一:forEach遍历构建,直观易懂 const sortedPresets = {}; sortedKeys.forEach(key => { sortedPresets[key] = presets[key]; // 直接复用原对象,不修改原始数据 }); // 方式二:用Object.fromEntries更简洁 // const sortedPresets = Object.fromEntries( // sortedKeys.map(key => [key, presets[key]]) // );
步骤2:安全写入文件
不要用appendFile逐个写入(异步操作容易导致顺序混乱或遗漏),直接把整个排序后的对象转成JSON字符串,一次性写入文件:
const fs = require('fs').promises; // 使用Promise版本的fs,处理异步更可靠 async function saveSortedData() { try { // 把对象转成格式化的JSON字符串(null和2是缩进参数,可选,让JSON更易读) const jsonContent = JSON.stringify(sortedPresets, null, 2); await fs.writeFile('./data.json', jsonContent); console.log('排序后的数据已成功写入文件!'); } catch (error) { console.error('写入文件时出错:', error); } } saveSortedData(); // 如果喜欢用同步方法(适合小文件,大文件推荐异步): // const fs = require('fs'); // try { // const jsonContent = JSON.stringify(sortedPresets, null, 2); // fs.writeFileSync('./data.json', jsonContent); // console.log('写入成功!'); // } catch (error) { // console.error('写入出错:', error); // }
关键说明
- 原始数据无修改:我们基于原对象的键排序后构建新对象,原
presets对象保持完全不变。 - 顺序可靠保留:现代JavaScript环境(Node.js、Chrome等)都支持ES6对象的插入顺序保留,读取
data.json解析后的对象会和我们排序的顺序一致。 - 彻底避免数据丢失:一次性写入整个对象,不会因为遍历中断或异步遗漏导致数据缺失。
内容的提问来源于stack exchange,提问作者Earth




