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"));
@aekryz1993
Copy link

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: unknown, filter?: unknown): HouseWithID[] {
  const housesData = typeof houses === "string" ? JSON.parse(houses) : houses;
  const housesWithIds = housesData.map((house: House, idx: number) => ({
    id: idx,
    ...house,
  }));
  return housesWithIds.filter(filter);
}

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

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

@soymikey
Copy link

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

interface HouseWithID extends House {
    id: number
}

const houses: House[] = [
    { "name": "Atreides", "planets": "Calladan" },
    { "name": "Corrino", "planets": ["Kaitan", "Salusa Secundus"] },
    { "name": "Harkonnen", "planets": ["Giedi Prime", "Arrakis"] }
]
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) {
    const tempHouses: House[] = typeof houses === 'string' ? JSON.parse(houses) : houses
    return tempHouses.map(house => ({ id: tempHouses.indexOf(house), ...house }))

}



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

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

@sansarun
Copy link

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(
  houses: string | House[],
  filter?: (house: House) => boolean
) {
  const genId = () => Math.floor(Math.random() * 1000);
  const parsedHouses = typeof houses === "string" ? JSON.parse(houses) : houses;
  const housesWithId = parsedHouses.map((h: House) => ({ ...h, id: genId() }));
  return filter ? housesWithId.filter(filter) : housesWithId;
}

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

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

@berkaygurcan
Copy link

Hello!

Here is my solution :) . I got stuck in some places and looked at the video for an idea. It wasn't very good :/ .(I couldn't understand what was asked because my English level is not good, but I solved it later :))

//My solution
import houses from "./houses";

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

interface HouseWithID {
  id: number;
  name: string;
  planets: string | 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: string | House[],
  filter?: (house: House) => boolean
): HouseWithID[] {
  const houses = typeof input === "string" ? JSON.parse(input) : input;

  houses.forEach((house: HouseWithID, i: number) => {
    //added if for each house item
    house.id = i + 1;
  });

  const result = filter ? houses.find((house: House) => filter(house)) : houses;

  return result;
}

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

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

@Rauraurautis
Copy link

Rauraurautis commented May 31, 2022

My Approach:

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;
}

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 (typeof houses === 'string') houses = JSON.parse(houses);

	let housesWithId: HouseWithID[] = (houses as House[]).map((updatedHouse) => ({
		id: Math.random().toString(36).substr(2, 9),
		...updatedHouse,
	}));
	if (filter) housesWithId = housesWithId.filter(filter);

	return housesWithId;
}

Thanks a lot for this, really learnt a lot. So much better than my code which was 3 times longer lol

@RichardPriddy
Copy link

Really enjoying the series, feel a little late to the party, but with a little refactoring I manged to find a simple one line solution:

import houses from './houses.json';

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(houses: string | House[], filter: (house: House) => boolean = () => true): HouseWithID[] {
    return (typeof(houses) === "string" ? (JSON.parse(houses) as House[]) : houses)
            .map(h => {return {id: h.name, ...h}})
            .filter(filter);
}

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

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

However, the find houses function may be more readable as this:

function findHouses(houses: string | House[], filter: (house: House) => boolean = () => true): HouseWithID[] {
    const parseHouses = (houses: string | House[]): House[] => {
        return typeof(houses) === "string" ? (JSON.parse(houses) as House[]) : houses;
    }

    return parseHouses(houses)
            .map(h => {return {id: h.name, ...h}})
            .filter(filter);
}

@deamon-cool
Copy link

deamon-cool commented Jun 27, 2022

There are plenty of great solutions up there, so some refactored approach from my side.
PS Jack, thank you for all the awesome series about ts.

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: number;
}

type HousesParam = string | House[];

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

function findHouses(houses: HousesParam): HouseWithID[];
function findHouses(houses: HousesParam, filter: FilterFun): HouseWithID[];

function findHouses(houses: unknown, filter?: unknown) {
  let housesWithID: HouseWithID[] = [];
  let l_houses: House[] = [];

  if (typeof houses === 'string') {
    l_houses = JSON.parse(houses);
  }

  if (Array.isArray(houses)) {
    l_houses = houses;
  }

  l_houses.forEach((item, i) => {
    housesWithID.push({
      id: i,
      ...item,
    });
  });

  if (typeof filter === 'function') {
    return housesWithID.filter(filter as FilterFun);
  }

  return housesWithID;
}

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

@wtfzambo
Copy link

this is how I implemented it. Took me a while but definitely not a full GoT season 😄

import houses from "./houses";

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(input: House[] | string, filter?: (house: House) => boolean): HouseWithID[] {
  let houses: House[];
  let housesWithId: HouseWithID[];

  typeof input === "string" ? (houses = JSON.parse(input)) : (houses = input);

  housesWithId = houses.map((house, id) => ({ ...house, id }));
  housesWithId = filter ? housesWithId.filter(filter) : housesWithId;

  return housesWithId;
}

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

@azubikeenu
Copy link

import fs from 'fs';

type House = {
  name: string;
  planets: string | Array<string>;
};

type HouseWithID = {
  id: number;
} & House;

const houses = fs.readFileSync('houses.json', 'utf-8');

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(
  param: unknown,
  filter?: (house: House) => boolean
): HouseWithID[] {
  let houseWithID: HouseWithID[] = [];
  const housesArray: House[] = typeof param === 'string' ? JSON.parse(houses) : param;
  houseWithID = housesArray.map((house, idx) => ({ id: idx, ...house }));
  return filter ? houseWithID.filter(filter) : houseWithID;
}

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

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

const houseObj: House[] = JSON.parse(houses);
console.log(findHouses(houseObj, ({ 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