'Simple way to force javascript to always return an array
I stumbled upon the YQL API to query for WOEIDs for use in Twitter, but I can see the output is not always in array. The API returns an object and I'm interested in value of response.query.results which returns the following:
- if there are no results, it returns null
- if there is only one result, it returns an object
- if the are multiple results, it returns an array
I want the result to always be an array. I can solve this by checking the result using the following code:
var count = response.query.count;
if(count === 0) {
return [];
} else if(count === 1) {
var arr = [];
arr.push(response.query.results);
return arr;
} else {
return response.query.results;
}
Is there a javascript or lodash function that can simplify the above code? It seems _.forEach and _.toArray will treat each property as an object if provided with a single object.
Solution 1:[1]
https://lodash.com/docs/4.17.4#concat
_.concat([],response.query.results);
would also do it.
but as @Brian pointed out, we need to handle null being equivalent to [] so you can add
_.concat([],_.isNull(response.query.results)?[]:response.query.results);
note that this is more correct because it will work for results with falsey values (like 0 and false etc)
in general, lodash is more robust than built in javascript. this usually works in your favour. one place this can trip you up is if results was a string (which is an array of characters)
https://github.com/lodash/lodash/blob/4.17.4/lodash.js#L6928
function concat() {
var length = arguments.length;
if (!length) {
return [];
}
var args = Array(length - 1),
array = arguments[0],
index = length;
while (index--) {
args[index - 1] = arguments[index];
}
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
}
Solution 2:[2]
Similar to Tom's answer above, the lodash function castArray (https://lodash.com/docs/4.17.15#castArray), introduced in Lodash v4.4, could also work for this. It has the marginal benefit that its intent is slightly more clear that [].concat(x)
const _ = require('lodash')
_.castArray(null) // [null]
_.castArray({a:1}) // [{a:1}]
_.castArray([{a:1},{a:2}] // [{a:1},{a:2}]
To deal with the null, considerations are similar to answers above, depending on how you want to handle unexpected values. A ternary with _.isNull would work, or else ?? is useful, e.g.:
const castArrayRemovingNullUndef = x => _.castArray(x ?? [])
const castArrayRemovingNull = x => _.castArray(_.isNull(x) ? [] :x)
_.castArrayRemovingNull(null) // []
_.castArrayRemovingNull({a:1}) // [{a:1}]
_.castArrayRemovingNull([{a:1},{a:2}] // [{a:1},{a:2}]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
