I have an object in Javascript as follows:
profile= {
profilePicture: null,
username: null,
age: null,
gender: null,
followedBy: [],
following: [],
aboutMe: null
}
And I would like to destructure all of the properties into variables, like such:
const {userName, age, gender, followedBy, following, aboutMe} = profile
Let's say in the future this profile object will have 30 properties, how can I iterate over all the properties instead of typing them one by one? I was thinking something like this
const {userName, age, ...rest} = profile
but instead of the rest variable, it actually gives me all the other property names as stand-alone variable names that I can use. I tried something like
const {...Object.keys(profile)} = profile
but it's not working.
Any ideas?
Simply change the curly bracket to square bracket
For Example
const [userName, age, gender, followedBy, following, aboutMe] = profile
const [userName, age, ...rest] = profile
Related
I have 2 enums, const Option1 = z.enum(["option1"]) and const Option2 = z.enum(["option2"]).
I want to merge these two into z.ZodEnum<["option1", "option2"]>
The only way I came up with so far is
export const Options = z.enum([
...Option1.options,
...Option2.options,
]);
// Options.options is now ["option1", "option2"]
Is there any zod native way to do this?
the issue you're facing here is due to the type of the combined options.
const allOptions = [...Option1.options, ...Option2.options]
the inferred type of allOptions in this case is: ("option1" | "option2")[] and zod can't create an enum out of that.
however, if you define allOptions like this:
const allOptions = [...Option1.options, ...Option2.options] as const
then the inferred type of allOptions will be the tuple ["option1", "option2"] which is exactly what you want.
so, putting that all together, to combine the options, you'd say:
const Options = z.enum([...Option1.options, ...Option2.options] as const)
and the inferred type of Options will be z.ZodEnum<["option1", "option2"]>
I have a range of data in a Google Sheet and I want to store that data into an array using the app script. At the moment I can bring in the data easily enough and put it into an array with this code:
var sheetData = sheet.getSheetByName('Fruit').getRange('A1:C2').getValues()
However, this puts each row into an array. For example, [[Apple,Red,Round],[Banana,Yellow,Long]].
How can I arrange the array by columns so it would look: [[Apple,Banana],[Red,Yellow],[Round,Long]].
Thanks.
It looks like you have to transpose the array. You can create a function
function transpose(data) {
return (data[0] || []).map (function (col , colIndex) {
return data.map (function (row) {
return row[colIndex];
});
});
}
and then pass the values obtained by .getValues() to that function..
var sheetData = transpose(sheet.getSheetByName('Fruit').getRange('A1:C2').getValues())
and check the log. See if that works for you?
Use the Google Sheets API, which allows you to specify the primary dimension of the response. To do so, first you must enable the API and the advanced service
To acquire values most efficiently, use the spreadsheets.values endpoints, either get or batchGet as appropriate. You are able to supply optional arguments to both calls, and one of which controls the orientation of the response:
const wb = SpreadsheetApp.getActive();
const valService = Sheets.Spreadsheets.Values;
const asColumn2D = { majorDimension: SpreadsheetApp.Dimension.COLUMNS };
const asRow2D = { majorDimension: SpreadsheetApp.Dimension.ROWS }; // this is the default
var sheet = wb.getSheetByName("some name");
var rgPrefix = "'" + sheet.getName() + "'!";
// spreadsheetId, range string, {optional arguments}
var single = valService.get(wb.getId(), rgPrefix + "A1:C30");
var singleAsCols = valService.get(wb.getId(), rgPrefix + "A1:C30", asColumn2D);
// spreadsheetId, {other arguments}
var batchAsCols = valService.batchGet(wb.getId(), {
ranges: [
rgPrefix + "A1:C30",
rgPrefix + "J8",
...
],
majorDimension: SpreadsheetApp.Dimension.COLUMNS
});
console.log({rowResp: single, colResp: singleAsCols, batchResponse: batchAsCols});
The reply will either be a ValueRange (using get) or an object wrapping several ValueRanges (if using batchGet). You can access the data (if any was present) at the ValueRange's values property. Note that trailing blanks are omitted.
You can find more information in the Sheets API documentation, and other relevant Stack Overflow questions such as this one.
I think my question is easy, but nonetheless I could not find an answer anywhere.
I want to typecheck a function, but what I cannot seem to do is bind the return type to the input type.
Say I have a deck of cards that is typed, and I want a (imaginairy) return type that depends on the input given an existing mapping.
The deck with the function:
type Suit = "diamonds" | "clubs" | "hearts" | "spades"
const suitMapping = {
"diamonds": ["are", "forever"],
"clubs": ["fabric", "fuse"],
"hearts": ["she", "loves", "me"],
"spades": ["lemmy", "loud"]
}
const suitToList = (suit: Suit) => {
return suitMapping[suit]
}
So for instance, I know that suitToList("diamonds") will return ["are", "forever"]. And the mapping in the object is fixed and computer generated. But I would love it if there would be a way to typespec the mapping with Flow. That way, if somewhere down the road someone wants to add "motorhead" to "spades", the typecheck would fail at first, so the functions depending on the output could be checked.
For now, I have tests for it, but somewhere I feel this could be possible with Flow too.
I find a way to typecheck this, but with usage of any. Not too clean way, but I think it's a flow bug. See https://github.com/facebook/flow/issues/2057#issuecomment-395412981
type Suit = "diamonds" | "clubs" | "hearts" | "spades"
type SuitMapping = {
diamonds: string,
clubs: number,
hearts: Array<string>,
spades: Array<string>,
}
const suitMapping: SuitMapping = {
"diamonds": '',
"clubs": 1,
"hearts": ["she", "loves", "me"],
"spades": ["lemmy", "loud"]
}
const suitToList = <K: Suit>(suit: K): $ElementType<SuitMapping, K> => {
return (suitMapping[suit]: any);
}
// suitToList('xxx'); // error
// const x: number = suitToList('diamonds'); // error
const y: string = suitToList('diamonds'); // works
See on flow try
I am trying to use the type ImageURISource which is here - https://github.com/facebook/react-native/blob/26684cf3adf4094eb6c405d345a75bf8c7c0bf88/Libraries/Image/ImageSource.js#L15
type ImageURISource = {
uri?: string,
bundle?: string,
method?: string,
headers?: Object,
body?: string,
cache?: 'default' | 'reload' | 'force-cache' | 'only-if-cached',
width?: number,
height?: number,
scale?: number,
};
export type ImageSource = ImageURISource | number | Array<ImageURISource>;
However we see that it is exported as a union along with 2 other things. Is it possible to pick from a union just one?
I was hoping to do:
$Pick<ImageSource, ImageURISource>
It's not very pretty, but you could use refinement to specifically refine the type that you want out of it by doing something like this:
var source: ImageSource = {}
if (typeof source === "number" || Array.isArray(source)) throw new Error();
var uriSource = source;
type ImageURISource = typeof uriSource;
The downside here is that if the add more types to the union, your code would start failing again.
It seems like you'd be best off making a PR to react-native to expose that type.
I am using redux and immutablejs, and I am trying to create a reducer function.
I have come across some behaviour I did not expect
const a = new Immutable.Map({
numbers: [{id: 1},{id: 2}]
});
const b = a.merge(
{
numbers: [{id: 4},{id: 5}]
}
);
Here are the values of a and b
a.get("numbers");
[Object, Object]
b.get("numbers");
List {size: 2, _origin: 0, _capacity: 2, _level: 5, _root: null…}
b.get("numbers").get(0);
Map {size: 1, _root: ArrayMapNode, __ownerID: undefined, __hash: undefined, __altered: false}
I did not expect numbers to be an immutable List of Map objects.
In my application, using redux, I set the initial state to:
const initialState = new Immutable.Map({
error: null,
isBusy: false,
films: []
});
I the reducer, when I fetch films I try to merge them as follows:
return state.merge({
isBusy: false,
films: action.payload,
error: null
});
This causes issues in the react component, as films are initially an array of objects, and then they become an Immutable List of Maps.
Should I create a different initial state, or should I be using a different type of merge? Or something else?
Thanks
I think what you are trying to do is not merge of whole map object, at least should not be in the case you say, it should be update + ( concat or merge ):
const a = new Immutable.Map({
numbers: [{id: 1},{id: 2}]
});
const b = a.update("numbers", numbers =>
numbers.concat([{id: 4},{id: 5}])
// or
numbers.merge([{id: 4},{id: 5}])
);
by doing merge in your code, you are overriding the existing ones due to the nature of "merge" because the keys are the same in the merge; "numbers".