简体   繁体   中英

Convert firebase array-like object to array

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM