Skip to content

Instantly share code, notes, and snippets.

@jherr
Created April 17, 2021 20:57
Show Gist options
  • Save jherr/cd442b46070b39e99dd8bedc9eecff5c to your computer and use it in GitHub Desktop.
Save jherr/cd442b46070b39e99dd8bedc9eecff5c to your computer and use it in GitHub Desktop.
Challenge #1
[
{ "name": "Atreides", "planets": "Calladan" },
{ "name": "Corrino", "planets": ["Kaitan", "Salusa Secundus"] },
{ "name": "Harkonnen", "planets": ["Giedi Prime", "Arrakis"] }
]
interface House {
...
}
interface HouseWithID {
...
}
function findHouses(houses: string): HouseWithID[];
function findHouses(
houses: string,
filter: (house: House) => boolean
): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(
houses: House[],
filter: (house: House) => boolean
): HouseWithID[];
console.log(
findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides")
);
console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));
@arditnurcaj
Copy link

interface House {
	name: string;
	planets: string | string[];
}

interface HouseWithID extends House {
	id: string;
}

function generateUniqueID(): string {
	return (
		'house-' + new Date().getMilliseconds() + Math.floor(Math.random() * 1000)
	);
}

function findHouses(houses: string): HouseWithID[];
function findHouses(
	houses: string,
	filter: (house: House) => boolean
): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(
	houses: House[],
	filter: (house: House) => boolean
): HouseWithID[];
function findHouses(
	houses: unknown,
	filter?: (house: House) => boolean
): HouseWithID[] {
	if (!houses) return [];

	let modifiedHouses: House[] = [];

	try {
		if (typeof houses === 'string') {
			modifiedHouses = JSON.parse(houses);
		} else {
			modifiedHouses = houses as House[];
		}

		if (filter) {
			modifiedHouses = modifiedHouses.filter(filter);
		}
	} catch (error) {
		console.log('Wrong data on houses!');
	}

	return modifiedHouses.map((house) => ({ ...house, id: generateUniqueID() }));
}

console.log(
	findHouses(JSON.stringify(houses), ({ name }) => name === 'Atreides')
);

console.log(findHouses(houses, ({ name }) => name === 'Harkonnen'));

@javierportillo
Copy link

javierportillo commented Sep 29, 2022

My version

const houses = [
  { name: "Atreides", planets: "Calladan" },
  { name: "Corrino", planets: ["Kaitan", "Salusa Secundus"] },
  { name: "Harkonnen", planets: ["Giedi Prime", "Arrakis"] },
];

interface House {
  name: string;
  planets: string | string[];
}

interface HouseWithID extends House {
  id: string;
}

type houseFilter = (house: House) => boolean

function findHouses(houses: string): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(houses: string, filter: houseFilter): HouseWithID[];
function findHouses(houses: House[], filter: houseFilter): HouseWithID[];

function findHouses(houses: string | House[], filter?: houseFilter): HouseWithID[] {
  if (typeof houses === "string") {
    houses = JSON.parse(houses) as House[]
  }

  houses = houses.map((house, idx) => ({
    ...house,
    id: `${idx + 1}`,
  }));

  if (filter) {
    houses = houses.filter(filter);
  }

  return houses as HouseWithID[]
}

console.log(findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides"));
console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));

@strangeiot
Copy link

strangeiot commented Oct 21, 2022

My Approach after watching the tutorial

const houses = [
    { "name": "Atreides", "planets": "Calladan" },
    { "name": "Corrino", "planets": ["Kaitan", "Salusa Secundus"] },
    { "name": "Harkonnen", "planets": ["Giedi Prime", "Arrakis"] }
]

interface House {
    name: string;
    planets: string | string[];
}

interface HouseWithID extends House {
    ID: string
}

function findHouses(houses: string): HouseWithID[];
function findHouses(houses: string, filter: (house: House) => boolean): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(houses: House[], filter: (house: House) => boolean): HouseWithID[];

function findHouses(input: unknown, filter?: (house: House) => boolean): HouseWithID[] {
    let housesWithId: HouseWithID[] = []
    let houses: House[] = []
    if (typeof input === "string") {
        houses = JSON.parse(input) as House[]
    } else{
        houses = input as House[]
    }
    housesWithId = houses.map((data: House, index: number) => {
        return {
            ID: index.toString(),
            name: data.name,
            planets: data.planets
        }
    })
    if (filter) {
        housesWithId = housesWithId.filter(filter)
    }

    return housesWithId
}
console.log(findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides"));
console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));

Thank you @jherr

@muhammadtalha242
Copy link

muhammadtalha242 commented Dec 6, 2022

Here is my approach.

interface HouseWithID extends House {
  id: number;
}

type housesInput = House[] | string;
type housesFilter = (house: House) => boolean;

function findHouses(houses: housesInput, filter?: housesFilter): HouseWithID[] {
  let housesArr: House[] =
    typeof houses === "string" ? JSON.parse(houses) : houses;
  let housesWithIDArr: HouseWithID[] = housesArr.map(
    (house: House, id: number) => ({
      id,
      ...house,
    })
  );
  housesWithIDArr = filter ? housesWithIDArr.filter(filter) : housesWithIDArr;
  return housesWithIDArr;
}

console.log(
  findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides")
);

console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));

Thank you @jherr

@theaungmyatmoe
Copy link

theaungmyatmoe commented Jan 14, 2023

Description can be found here.
https://gist.github.com/amm834/3de41ccf4f296a92aa9b382b0fbfc49e

KISS

interface House {
    name: string;
    planets: string | string[];
}

interface HouseWithID extends House {
    id: number;
}

type TFilterFn = (house: House) => boolean;

function findHouses(houses: string): HouseWithID[];
function findHouses(
    houses: string,
    filter: TFiler
): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(
    houses: House[],
    filter: TFilterFn
): HouseWithID[];
function findHouses(arg1: unknown, filter?: TFilterFn): HouseWithID[] {
    const houses = Array.isArray(arg1) ? arg1 : JSON.parse(arg1);

    const housesWithID = houses.map((house, index) => ({
        ...house,
        id: index,
    }));
    return filter ? housesWithID.filter(filter) : housesWithID;
}


const houses = [
    {"name": "Atreides", "planets": "Calladan"},
    {"name": "Corrino", "planets": ["Kaitan", "Salusa Secundus"]},
    {"name": "Harkonnen", "planets": ["Giedi Prime", "Arrakis"]}
]


console.log(
    findHouses(JSON.stringify(houses), ({name}) => name === "Atreides")
);

console.log(findHouses(houses, ({name}) => name === "Harkonnen"));
console.log(findHouses(houses));

@Hachikoi-the-creator
Copy link

Hachikoi-the-creator commented Feb 3, 2023

I can't sleep so I decided to continue this tutorials and surpsingly worked!
Also got distracted looking for diference between interface & type so I found out about extends

interface House {
  name: string;
  planets: string | string[];
}

interface HouseWithID extends House {
  id: number;
}

type FilterCB = (house: House) => boolean;
// overload
function findHouses(houses: string): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(houses: string, filter: FilterCB): HouseWithID[];
function findHouses(houses: House[], filter: FilterCB): HouseWithID[];

// implementation
function findHouses(
  houses: string | House[],
  filter?: FilterCB
): HouseWithID[] {
  if (typeof houses === "string" && !!filter) {
    const parsed: HouseWithID[] = (JSON.parse(houses) as House[]).map(
      (h, i) => ({ ...h, id: i })
    );

    return filter ? parsed.filter((h) => filter(h)) : parsed;
  }

  const casted = (houses as House[]).map((h, i) => ({ ...h, id: i }));
  return filter ? casted.filter((h) => filter(h)) : casted;
}

@PhilippAubert
Copy link

Ok, so here I go.

A little verbose, but I'm happy with it 😸


const houses = [
  { "name": "Atreides", "planets": "Calladan" },
  { "name": "Corrino", "planets": ["Kaitan", "Salusa Secundus"] },
  { "name": "Harkonnen", "planets": ["Giedi Prime", "Arrakis"] }
]

interface House {
    name:string,
    planets:string|string[]
}

interface HouseWithID {
    house:House,
    id:number
}

const findHouses = (houses:House[], filter?:(house:House)=>boolean):HouseWithID[] => {
    let houseWithIds:HouseWithID[] = [];
    if (filter) {
        houses = houses.filter(filter);
    }
        houses.map((house:House, id:number)=> {
            id+=1;
            let newHouse:HouseWithID = {
                house:{
                    name:house.name,
                    planets:house.planets
                },
                id:id
            }
            houseWithIds.push(newHouse);
            return houseWithIds;
        })
    return houseWithIds;
}

@mateuszjansowa
Copy link

Thanks for challenge! 👍

My solution:

import houses from "./houses.json";

interface House {
  name: string;
  planets: string | string[];
}

interface HouseWithID extends House {
  id: number;
}

type HouseFilter = (v: House) => boolean;

function findHouses(arg1: unknown, arg2?: HouseFilter): HouseWithID[] {
  const houses: House[] = Array.isArray(arg1)
    ? [...arg1]
    : JSON.parse(arg1 as string);

  const mappedHouses: HouseWithID[] = houses.map((v: House, i: number) => ({
    ...v,
    id: i
  }));

  if (arg2 && typeof arg2 === "function") {
    return mappedHouses.filter(arg2);
  }

  return mappedHouses;
}

console.log(
  findHouses(JSON.stringify(houses), ({ name }) => name === "Harkonnen")
);

@jaxkashif34
Copy link

const houses: House[] = [
  { name: 'Atreides', planets: 'Calladan' },
  { name: 'Corrino', planets: ['Kaitan', 'Salusa Secundus'] },
  { name: 'Harkonnen', planets: ['Giedi Prime', 'Arrakis'] },
];

interface House {
  name: string;
  planets: string | string[];
}

interface HouseWithID extends House {
  id: number;
}

function findHouses(houses: string | House[], filter: (house: House) => boolean): HouseWithID[] {
  const housesJSON = typeof houses === 'string' ? JSON.parse(houses) : houses;
  const housesWithID: HouseWithID[] = housesJSON.map((house: House, index: number) => ({ ...house, id: index }));

  return housesWithID.filter(filter);
}

console.log(findHouses(JSON.stringify(houses), ({ name }) => name === 'Atreides'));
console.log(findHouses(houses, ({ name }) => name === 'Harkonnen'));

@khanhledev
Copy link

@jherr thank you so much for amazing series. This is my solution:

import data from "./houses.json";
interface House {
  name: string;
  planets: string | string[];
}

interface HouseWithID extends House {
  id: number;
}

type HouseFilter = (house: House) => boolean;

function findHouses(
  input: House[] | string,
  filter: HouseFilter
): HouseWithID[] {
  let houses: HouseWithID[] = [];
  if (typeof input === "string") {
    input = JSON.parse(input) as House[];
  }

  houses = input.map((item: House, index: number) => ({
    ...item,
    ...{ id: index },
  }));
  if (filter) {
    houses = houses.filter(filter);
  }

  return houses;
}

console.log(
  findHouses(JSON.stringify(data), ({ name }) => name === "Atreides")
);

console.log(findHouses(data, ({ name }) => name === "Harkonnen"));

@dzulfiqarzaky
Copy link

const houses = require("./houses.json");

interface House {
    name: string;
    planets: string | string[];
}

interface HouseWithID extends House {
    id: number;
}
type Filter = (house: House) => boolean;

function findHouses(houses: string): HouseWithID[];
function findHouses(houses: string, filter: Filter): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(houses: House[], filter: Filter): HouseWithID[];
function findHouses(houses: unknown, filter?: Filter): HouseWithID[] {
    if (houses == null) {
        return [];
    }
    let house: HouseWithID[] = [];

    if (typeof houses === "string") {
        house = (JSON.parse(houses) as House[]).map((housemap) => ({
            ...housemap,
            id: Math.random(),
        }));
    } else {
        house = (houses as House[]).map((housemap) => ({
            ...housemap,
            id: Math.random(),
        }));
    }

    if (typeof filter === "function") {
        return house.filter(filter);
    }
    return house;
}

console.log(
    findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides")
);

console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));

@nazifbara
Copy link

const houses: House[] = [
  { name: "Atreides", planets: "Calladan" },
  { name: "Corrino", planets: ["Kaitan", "Salusa Secundus"] },
  { name: "Harkonnen", planets: ["Giedi Prime", "Arrakis"] },
];

interface House {
  name: string;
  planets: string | string[];
}

interface HouseWithID extends House {
  ID: string;
}

type FilterFn = (house: House) => boolean;

function findHouses(houses: string): HouseWithID[];
function findHouses(houses: string, filter: FilterFn): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(houses: House[], filter: FilterFn): HouseWithID[];
function findHouses(arg1: unknown, arg2?: FilterFn): HouseWithID[] {
  let houses: House[] = [];

  // Parse if arg1 is a string
  if (typeof arg1 === "string") {
    houses = JSON.parse(arg1);
  } else if (typeof arg1 === "object") {
    houses = arg1 as House[];
  }

  // Filter if there is a filter function
  houses = arg2 ? houses.filter(arg2) : houses;

  // Create the houses with IDs and return them
  return houses.map((house, idx) => ({
    ID: `${house.name}#${idx}`,
    ...house,
  }));
}

console.log(
  findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides")
);

console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));

@ozgursar
Copy link

ozgursar commented Aug 12, 2023

import houses from './houses.json'

interface House {
  name: string
  planets: string | string[]
}

interface HouseWithID extends House {
  id: number
}

function findHouses(houses: string): HouseWithID[]

function findHouses(houses: string, filter: (house: House) => boolean): HouseWithID[]

function findHouses(houses: House[]): HouseWithID[]

function findHouses(houses: House[], filter: (house: House) => boolean): HouseWithID[]

function findHouses(houses: string | House[], filter?: (house: House) => boolean): HouseWithID[] {
  let houseList: House[] = []
  if (typeof houses === 'string') {
    houseList = JSON.parse(houses)
  } else {
    houseList = houses
  }
  const housesWithID: HouseWithID[] = houseList.map((house, index) => ({ id: index, ...house }))

  if (filter) {
    return housesWithID.filter(filter)
  } else {
    return housesWithID
  }
}

console.log(findHouses(JSON.stringify(houses), ({ name }) => name === 'Atreides'))

console.log(findHouses(houses, ({ name }) => name === 'Harkonnen'))

@lovenangelo
Copy link

lovenangelo commented Aug 15, 2023

const houses : House[] = [
  { "name": "Atreides", "planets": "Calladan" },
  { "name": "Corrino", "planets": ["Kaitan", "Salusa Secundus"] },
  { "name": "Harkonnen", "planets": ["Giedi Prime", "Arrakis"] }
]

interface House {
  name: string,
  planets: string | string[]
}

interface HouseWithID extends House {
  id: number
}

function findHouses(houses: string): HouseWithID[];
function findHouses(
  houses: string,
  filter: (house: House) => boolean
): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(
  houses: House[],
  filter: (house: House) => boolean
): HouseWithID[];

function findHouses(house: string | House[], filter?: (house: House)=>boolean): HouseWithID[]{

  let housesWithId : HouseWithID[] | [] = [];

  const addHouseId = (houseList: House[] = house as House[]): HouseWithID[] =>{
    return houseList.map((house: House, index) => {
      return {
        ...house,
        id: index+1
      }
    })
  }

  const filterHouse = (housesWithId: HouseWithID[]) => {
    return housesWithId.filter(filter!);
  }

  if(typeof house == 'string'){
    const parsedHouse : House[] = JSON.parse(house)
    housesWithId = addHouseId(parsedHouse)
  }else{
    housesWithId = addHouseId()
  }

  if(filter){
    const house = filterHouse(housesWithId);
    return house;
  }
  
  return housesWithId;
}

console.log(findHouses(JSON.stringify(houses), ({ name }) => name === 'Atreides'))

console.log(findHouses(houses, ({ name }) => name === 'Harkonnen'))

@Elle0320
Copy link

import houses from './houses.json';

interface House {
name: string;
planets: string|string[];
}

interface HouseWithID extends House{
id: string;
}

function findHouses(
input: House[]| string,
filter?: (house: House) => boolean
): HouseWithID[]{
const houses = typeof input == "string"? JSON.parse(input) : input;
return (filter? houses.filter(filter) : houses)
.map((h:House)=>{
return {...h, id: houses.indexOf(h)}
})
};

console.log(
findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides")
);

console.log(findHouses(houses as any, ({ name }) => name === "Harkonnen"));

@AlanJereb
Copy link

const houses = [
  { "name": "Atreides", "planets": "Calladan" },
  { "name": "Corrino", "planets": ["Kaitan", "Salusa Secundus"] },
  { "name": "Harkonnen", "planets": ["Giedi Prime", "Arrakis"] }
];

// Challenge #1

interface House {
    name: string;
    planets: string | string[];
}

interface HouseWithID extends House {
    id: string;
}

function findHouses(houses: string): HouseWithID[];
function findHouses(
  houses: string,
  filter: (house: House) => boolean
): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(
  houses: House[],
  filter: (house: House) => boolean
): HouseWithID[];
function findHouses(arg: string | House[], f?: (house: House) => boolean): HouseWithID[] {
    let result: HouseWithID[] = [];
    let values: House[] = [];

    // Base
    if (typeof arg === "string") {
        values = JSON.parse(arg);
    } else {
        values = arg;
    }
    values.forEach((ar) => {
        result.push({
            ...ar,
            id: ar.name.charAt(0),
        })
    })
    // filter
    if (f) {
        result = result.filter(f);
    }

    return result;
}

console.log(findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides"));
console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));

@waraich1
Copy link

waraich1 commented Jan 12, 2024

Here's an easy to understand solution

  { name: "Atreides", planets: "Calladan" },
  { name: "Corrino", planets: ["Kaitan", "Salusa Secundus"] },
  { name: "Harkonnen", planets: ["Giedi Prime", "Arrakis"] },
];

interface House {
  name: string;
  planets: string | string[];
}

interface HouseWithID {
  name: string;
  planets: string | string[];
  id: number;
}

function findHouses(houses: string): HouseWithID[];

function findHouses(
  houses: string,
  filter: (house: House) => boolean
): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];

function findHouses(
  houses: House[],
  filter: (house: House) => boolean
): HouseWithID[];

function findHouses(
  input: string | House[],
  filter?: (house: House) => Boolean
) {
  const temp = (
    typeof input === "string" ? JSON.parse(input) : input
  ) as House[];
  let filteredHouses = filter ? temp.filter(filter) : temp;

  return filteredHouses.map(
    (house, id): HouseWithID => ({
      ...house,
      id,
    })
  );
}

console.log(
  findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides")
);

console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));

@kafkaphoenix
Copy link

in the tsconfig.json file you can enable "resolveJsonModule": true, so you can import the json file as import housesData from "./data/houses.json"; that way is an array

@Kahffi
Copy link

Kahffi commented Sep 6, 2024

interface House {
	name: string;
	planets: string | string[];
}
const houses: House[] = [
	{ name: "Atreides", planets: "Calladan" },
	{ name: "Corrino", planets: ["Kaitan", "Salusa Secundus"] },
	{ name: "Harkonnen", planets: ["Giedi Prime", "Arrakis"] },
];

interface HouseWithID extends House {
	id: number;
}

type FilterFunction = (houses: House) => boolean;

function addHouseId(houses: House[]): HouseWithID[] {
	return houses.map((house, index) => {
		const newHouse: HouseWithID = { ...house, id: index };
		return newHouse;
	});
}
function findHouses(houses: string): HouseWithID[];
function findHouses(houses: string, filter: FilterFunction): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(houses: House[], filter: FilterFunction): HouseWithID[];

function findHouses(arg1: unknown, arg2?: FilterFunction): HouseWithID[] {
	if (typeof arg1 === "string") arg1 = JSON.parse(arg1);
	if (arg2) {
		return addHouseId(arg1 as House[]).filter((house) => arg2(house));
	} else {
		return addHouseId(arg1 as House[]);
	}
}

console.log(
	findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides")
);

console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));

@fciurana
Copy link

Hi @jherr ,

Thanks for your series.

Here's my solution :

import data from "./houses.json";

interface House {
    name: string;
    planets: string[];
 }
    
interface HouseWithID {
    Id: number;
    House: House;
}

function findHouses(houses: string): HouseWithID[];
function findHouses(houses: string, filter?: (house: House) => boolean): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(houses: House[], filter?: (house: House) => boolean): HouseWithID[];
function findHouses(houses: unknown, filter?: (house: House) => boolean): HouseWithID[] {
    let housesWithId: HouseWithID[] = [];
    var i = 1;

    let houseArray = (typeof houses === `string` ? JSON.parse((houses as string)) : houses) as House[]; 

    houseArray.map(h => {
        if(filter?.(h))
            housesWithId.push({Id: i, House: h});
        i++;
    });
    
    return housesWithId;
}

console.log(
  findHouses(JSON.stringify(data), ({ name }) => name === "Atreides")
);

console.log(findHouses(data as any, ({ name }) => name === "Harkonnen"));

@ElMehdi-l
Copy link

import houses from "./houses.json";

interface House {
  name: string;
  planets: string | string[];
}

interface HouseWithID {
  id: number;
  house: House;
}

type FilterFunc = (house: House) => boolean;

function findHouses(houses: string): HouseWithID[];
function findHouses(houses: string, filter: FilterFunc): HouseWithID[];
function findHouses(houses: House[]): HouseWithID[];
function findHouses(houses: House[], filter: FilterFunc): HouseWithID[];

function findHouses(houses: unknown, filter?: unknown): HouseWithID[] {
  let housesWithID: HouseWithID[] = (
    typeof houses === "string" ? JSON.parse(houses) : houses
  ).map((house: House, index: number) => ({
    house,
    id: index + 1,
  }));

  if (typeof filter === "function") {
    housesWithID = housesWithID.filter((house: HouseWithID) =>
      (filter as FilterFunc)(house.house)
    );
  }

  return housesWithID;
}

console.log(findHouses(JSON.stringify(houses)));

console.log(
  findHouses(JSON.stringify(houses), ({ name }) => name === "Atreides")
);

console.log(findHouses(houses, ({ name }) => name === "Harkonnen"));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment