Skip to content

Instantly share code, notes, and snippets.

@mohamedelshorbagy
Created February 17, 2019 21:03
Show Gist options
  • Save mohamedelshorbagy/cf6612358de68d8dde32fdd4574b1d43 to your computer and use it in GitHub Desktop.
Save mohamedelshorbagy/cf6612358de68d8dde32fdd4574b1d43 to your computer and use it in GitHub Desktop.
/**
* Question 1
*/
//#region qs1
function groupBy(arr, prop) {
return arr.reduce((group, item) => {
let value = item[prop];
group[value] = group[value] || [];
group[value].push(item);
return group;
}, {})
}
const animalCollective = [
{ type: 'dog', name: 'bobi' },
{ type: 'fish', name: 'glup' },
{ type: 'fish', name: 'glup the second' },
{ type: 'cat', name: 'Aaron' }
];
let groupedByType = groupBy(animalCollective, 'type');
console.log(groupedByType);
// There's a improvement to this solution using another helper function to groupBy
function groupBy(arr, prop) {
return arr.reduce((group, item) => {
let value = getValue(item, prop);
group[value] = group[value] || [];
group[value].push(item);
return group;
}, {})
}
/**
*
* @param { Object } o
* @param { String, Array } p // ['type','name'] , 'type.name' , 'type'
* @return {*}
*/
function getValue(o, p) {
let paths = typeof p === "string" ? p.split('.') : p;
return paths.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o);
}
var animalCollective = [
{
type: {
name: 'dog',
id: 2
},
name: 'bobi'
},
{
type: {
name: 'fish', id: 3
},
name: 'glup'
},
{
type: {
name: 'fish',
id: 3
}
, name: 'glup the second'
},
{
type: {
name: 'cat',
id: 1
},
name: 'Aaron'
}
];
let groupedByType = groupBy(animalCollective, 'type.name');
console.log(JSON.stringify(groupedByType, null, 2));
//#endregion
//#region qs2
/**
* Question 2
*/
const arrayOfStrings = ['a', 'b', 'c'].forEach(v => 'a');
arrayOfStrings // undefined
// Because the forEach is like for loop it doesn't return an array or return anything it just
// loop over the array
//#endregion
//#region qs3
/**
* Question 3
*/
const arrayOfStrings = ['a', 'b', 'c'].map(v => 'a');
arrayOfStrings // ['a','a','a']
// Because the map is returning an array equals to the length of manipulated array
// you use fat arrow function which you return implicitly what after the => which here is 'a'
//#endregion
//#region qs4
/**
* Question 4
*/
const ben = { name: 'Ben', age: 2 };
const tom = { name: 'Tom', age: 3 };
const users = [ben, tom];
const userNames = users.map(user => user.name).join(); // 'Ben,Tom'
// userNames -> 'Ben,Tom'
// ben -> stay the same because you don't mutate the actual data
// users.map(user => user.name) ==> you return a new array which have only values in key 'name'
// ['Ben','Tom']
// Then you apply join function in the Array bellow which will concatenate them with comma ==> 'Ben,Tom'
//#endregion
//#region qs5
/**
* Question 5
*/
const ben = { name: 'Ben', age: 2 };
const tom = { name: 'Tom', age: 3 };
const users = [ben, tom];
const myNames = users.map(user => {
user.name = `My name is ${user.name}`;
}).join();
// myNames -> ','
// ben -> stay the same because you don't mutate the actual data
// users.map(user => {
// user.name = `My name is ${user.name}`;
// }) ==> you onlu mutate the user object in the map but you don't return any thing at the end
// so it will return a new array equals to the length of the manipulated array
// [undefined,undefined]
// Then you apply join function in the Array bellow which will concatenate them with comma ==> ','
// because join converts (undefined, null) to empty string
//#endregion
//#region qs6
/**
* Question 6
*/
// * Name 1 advantage and 1 disavantage of using immutable datastructures.
// Advantage: - Thread Safety
// - Temporal Coupling
// - Using Tries like immutable.js
// - Structural Sharing
// Disadvantages: - It doesn't reuse the memory again like mutation
//#endregion
//#region qs7
/**
* Question 7
*/
import { Subject } from 'rxjs';
import { scan } from 'rxjs/operators';
const actionDispatcher = new Subject();
const state$ = actionDispatcher.asObservable().pipe(scan((currentState, action) => {
switch (action.type) {
case 'reset':
return action.payload
case 'add':
return action.payload + currentState
}
throw new Error('Unkown action type');
}, 0));
state$.subscribe(state => console.log(state));
actionDispatcher.next({ type: 'add', payload: 1 });
actionDispatcher.next({ type: 'add', payload: 2 });
actionDispatcher.next({ type: 'reset', payload: 0 });
actionDispatcher.next({ type: 'add', payload: 3 });
// 1
// 3
// 0
// 3
// because here you use scan which is a small state management operator for rxjs which
// widely used in many angular or web applications instead of using redux or flux
// in every (.next) in actionDispatcher you send a value (or norify) the Subject with new value/action
// and you log the response (or new state) in the subscription (.subscribe) of the object
//#endregion
//#region qs8
/**
* Question 8
*/
function groupBy(arr: any[], prop: string) {
return arr.reduce((group: {}, item: {}) => {
let value: string = item[prop];
group[value] = group[value] || [];
group[value].push(item);
return group;
}, {})
}
interface IAnimal {
type: string,
name: string
}
const animalCollective: IAnimal[] = [
{ type: 'dog', name: 'bobi' },
{ type: 'fish', name: 'glup' },
{ type: 'fish', name: 'glup the second' },
{ type: 'cat', name: 'Aaron' }
];
let groupedByType: any = groupBy(animalCollective, 'type');
console.log(groupedByType);
/*************************** */
import { Subject } from 'rxjs';
import { scan } from 'rxjs/operators';
interface IAction {
type: string,
payload: number
}
const actionDispatcher: Subject<any> = new Subject();
const state$ = actionDispatcher.asObservable().pipe(scan((currentState: number, action: IAction) => {
switch (action.type) {
case 'reset':
return action.payload
case 'add':
return action.payload + currentState
}
throw new Error('Unkown action type');
}, 0));
state$.subscribe(state => console.log(state));
actionDispatcher.next({ type: 'add', payload: 1 });
actionDispatcher.next({ type: 'add', payload: 2 });
actionDispatcher.next({ type: 'reset', payload: 0 });
actionDispatcher.next({ type: 'add', payload: 3 });
//#endregion
//#region qs9
/**
* Question 9
*/
// * What is the difference between type checking at compiletime and type checking runtime ?
// * Compile-Time is to compile the code first to find out these checks which generate compile-time type checks due to
// * type mistake for appropriate syntax like Typescript, Flow
// * Runtime is checking the correctness of the type while the program is running like Flow-runtime, swift
// *
// * Which kind of type checking is used by typescript ?
// * Compile Time
// * there's some proposal to typescript to have some Runtime checks on it to be shipped with the generated source code
// * Which kind of type checking is used by javascript ?
// * Compile-Time & Runtime
//#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment