I use Firebase as a backend, and I often save arrays like this:
var arr = [null, "Pete", "Mary", null, null, null, null, null, "Joe"]
Since Firebase doesn't store arrays as arrays, when I retrieve the value, I get this:
{ 1: "Pete", 2: "Mary", 8: "Joe" }
This gets more complicated by the fact that I often store arrays of arrays, which sometimes are stored as follows:
{
1: { 1: "Pete", 2: "Mary", 8: "Joe" },
4: { 4: "Lisa" }
}
I would like to restore this object to the original array of arrays, which would be:
[
[null, null, null, null, null, null, null, null, null],
["Pete","Mary",null,null,null, null, null, null, "Joe"],
[null, null, null, null, null, null, null, null, null],
[null, null, null, null, null, null, null, null, null],
[null, null, null, null, "Lisa",null,null, null, null]
]
I implemented a function for the array of arrays, it works, but it feels very, very bad. There should be a much better way to do this:
function firebaseToRealArray(fbArray) {
if (Array.isArray(fbArray) || typeof fbArray === "undefined") {
return fbArray
} else {
var keyss = Object.keys(fbArray);
var height = +keyss[keyss.length - 1] + 1;
var resultArray = [];
var maxLength = _maxLength(fbArray, height)
for (var i = 0; i < height; i++) {
if (typeof fbArray[i] === "undefined") {
resultArray.push(_objToArray(fbArray[i], maxLength))
} else {
resultArray.push(_objToArray(fbArray[i], maxLength))
}
}
return resultArray;
}
}
function _maxLength(arr, height) {
var maxLength = 0;
for (var i = 0; i < height; i++) {
if (Array.isArray(arr[i])) {
maxLength = Math.max(maxLength, arr[i].length)
} else if (typeof arr[i] === "undefined") {
maxLength = Math.max(maxLength, 0);
} else {
maxLength = Math.max(maxLength, +Object.keys(arr[i])[Object.keys(arr[i]).length - 1]);
}
}
return maxLength + 1
}
function _objToArray(obj, l) {
if (typeof obj === "undefined") {
return _createArray(l, null)
}
var resArray = [];
for (var i = 0; i < l; i++) {
if (typeof obj[i] === "undefined") {
resArray.push(null);
} else {
resArray.push(obj[i]);
}
}
return resArray
}
function _createArray(len, itm) {
var arr1 = [itm],
arr2 = [];
while (len > 0) {
if (len & 1) arr2 = arr2.concat(arr1);
arr1 = arr1.concat(arr1);
len >>>= 1;
}
return arr2;
}
My first question is:
Is there a firebase function that I can use, client-side, to convert these array-like objects to actual arrays?
If not, my question becomes:
What is the best way to implement this function myself?
Or:
Is there something else that I'm totally overlooking?
I guess, beyond your 2D example for which the below snippet works just fine, it may get pretty nested as well. So my approach would would also handle that;
Our input is
{ 1: { 1: "Pete",
2: "Mary",
5: {1: "John",
3: "Terry" },
8: "Joe" },
4: { 4: "Lisa" }
};
and this is what we get;
[[null,null,null,null,null,null,null,null,null],
[[null,null,null,null],
["Pete",null,null,null],
["Mary",null,null,null],
[null,null,null,null],
[null,null,null,null],
[null,"John",null,"Terry"],
[null,null,null,null],
[null,null,null,null],
["Joe",null,null,null]],
[null,null,null,null,null,null,null,null,null],
[null,null,null,null,null,null,null,null,null],
[null,null,null,null,"Lisa",null,null,null,null]]
So;
function arrayishToArray(a){ var ok = Object.keys(a), arr; a.length = +ok[ok.length-1] + 1; arr = Array.from(a) .map(v => typeof v === "object" ? arrayishToArray(v) : v); return arr.map(function(sa){ return this.len ? Array.isArray(sa) ? sa.concat(Array(this.len - sa.length).fill(null)) : [sa || null].concat(Array(this.len-1).fill(null)) : sa; }, {len: Math.max(...arr.map(e => Array.isArray(e) ? e.length : 0))}); } var arrayish = { 1: { 1: "Pete", 2: "Mary", 5: {1: "John", 3: "Terry"}, 8: "Joe" }, 4: { 4: "Lisa" } }; console.log(JSON.stringify(arrayishToArray(arrayish)))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.