javascript - Mappa ett av tuplens element


Är det möjligt att mappa ett av elementen i en tupel enkelt i TypeScript? Jag letar efter en mjuk abstraktion över följande operation

const arr: [string, string][] = [['a', 'b'], ['c', 'd'], ['e', 'f']]

const f = (str: string): number => str.length

arr.map((row) => [row[0], f(row[1])])

mitt första försök var att implementera det som

function mapSnd<A, B, C>(arr: [A, B][], f: (B) => C): [A, C][] {
    return arr.map((row) => [row[0], f(row[1])])
}

men det skalar inte upp bra (för en tuppel med tre element skulle jag behöva definiera en ny uppsättning funktioner och så vidare), så jag letar efter en generell lösning

Svar #1

Du skrev great function men det finns ett litet problem enkelt - du använde B som ett parameternamn, inte typ. Använd detta:

const arr: [string, string][] = [['a', 'b'], ['c', 'd'], ['e', 'f']]
function mapSnd<A, B, C>(arr: [A, B][], f: (second: B) => C): [A, C][] {
    return arr.map(row => [row[0], f(row[1])]);
}
const res = mapSnd(arr, second => second.length); // [string, number][]

Och för fler som mapThrd utan separering finns det inget sätt, förlåt.

Svar #2

Här är en lösning som tillåter en godtycklig n-tupel att användas:

const arr: [string, string, string][] = [['a', 'bb', 'zzz'], ['c', 'ddd', 'qqqq'], ['e', 'ffff', 'rrrrr']]

const f = (str: string[]): number[] => str.map(s=>s.length);

const map = new Map();

arr.forEach(row => map.set(row.shift(), f(row)));

for (let [key, value] of map.entries()) {
  console.log(key + ' = ' + value)
}