如何排序Firebase嵌套对象数组且避免数据丢失?
2026-5-8
问题:按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);