le mie informazioni di contatto
Posta[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Questo articolo riassume le domande di codifica incontrate durante il processo di intervista.
Tieni presente che il vero valore restituito serve per la conservazione, non per il filtraggio, quindi non dimenticarlo. Non è niente, è solo che lo dimenticherò se non lo scriverò di persona per sei mesi. . .
arr.filter((elemento, indice, corrente) => {return arr.indexOf(elemento) == indice});.Può rimuovere il peso
L'essenza del filtro è creare un nuovo array e, se la funzione di callback restituisce true, verrà mantenuto. La riga di codice sopra significa che solo la prima volta viene inserita all'interno.
Deduplicazione a doppio puntatore:
Utilizzare i puntatori doppi per riordinare l'array. Se sono uguali, il puntatore veloce si sposterà di una posizione a destra. Se non sono uguali, il puntatore lento si sposterà di una posizione a destra il puntatore veloce a destra per il confronto con la volta successiva:
- function doublePointer(nums) {
- if(nums.length < 2) {
- return nums;
- }
- let slow = 0;
- let fast = 1;
- let result = [nums[0]];
- while(fast < nums.length) {
- if (result[slow] == nums[fast]) {
- fast++;
- } else {
- slow++;
- result[slow] = nums[fast];
- fast++;
- }
- }
- return result;
- }
- const arr = [1,1,2,2,4,4];
- console.log(doublePointer(arr));
Ingresso [1,1,2,2,4,4] e uscita [1,2,4].
Se l'array è un oggetto:
const arr2 = [{id:1,tempo: 2},{id:1,tempo: 4},{id:2,tempo: 2},{id:2,tempo: 4},{id:3,tempo: 5},
{id:3,ora: 2}];
Ora dobbiamo rimuovere i duplicati in base all'ID. Se gli ID sono uguali, verrà conservato solo l'oggetto con il tempo più grande.
[{"id":1,"ora":4},{"id":2,"ora":4},{"id":3,"ora":5}]
- function doublePointerByorder(nums) {
- if(nums.length < 2) {
- return nums;
- }
- let slow = 0;
- let fast = 1;
- let result = [nums[0]];
- while(fast < nums.length) {
- if (result[slow].id == nums[fast].id) {
- if(result[slow].time < nums[fast].time) {
- result[slow] = nums[fast];
- }
- fast++;
- } else {
- slow++;
- result[slow] = nums[fast];
- fast++;
- }
- }
- return result;
- }
console.log(doublePointerByorder(arr2)); Questo è tutto.
Naturalmente è possibile utilizzare un oggetto vuoto per ricordarlo, confrontare ogni volta l'ora corrispondente all'ID presente nell'oggetto e scegliere se sovrascriverlo. Dopo l'attraversamento, utilizzare un ciclo for in per convertire l'oggetto in un array. Tuttavia, i puntatori doppi sono molto efficienti. Se la quantità di dati è elevata, sarebbe più appropriato utilizzare i puntatori doppi.
L'assegnazione del segno uguale delle variabili di tipo riferimento non si influenzerà a vicenda.
Tuttavia, verrà influenzato dall'utilizzo di ab, che è considerata una copia superficiale, come mostrato di seguito.
- person1 = {name: 3};
- members = person1;
- members.name = 4; // person1.name=4
Diamo un'occhiata a un caso classico relativo alle citazioni. Anche questa è stata una domanda che non ho scritto quando l'ho incontrata per la prima volta durante l'intervista.
- function arrayToTree(items) {
- const tree = {};
- const map = {};
- items.forEach((item, index) => {
- const { id, parentId } = item;
- if (!map[id]) map[id] = { children: [] };
- const node = { ...item, children: map[id].children};
- map[id] = node;
- if (parentId) {
- if (!map[parentId]) {
- map[parentId] = { children: [] };
- } map[parentId].children.push(node);
- } else {
- tree[id] = node;
- }
- });
- console.log(map);
- }
-
- // 示例数组
- const items = [
- { id: 1, parentId: null, value: "A" },
- { id: 2, parentId: 1, value: "B" },
- { id: 3, parentId: 1, value: "C" },
- { id: 4, parentId: 2, value: "D" },
- { id: 5, parentId: 3, value: "E" }
- ];
-
- // 转换为树
- const tree = arrayToTree(items);
Puoi copiarlo direttamente per vedere l'effetto, proprio come una bambola matrioska russa. È facile capire quando il secondo strato viene aggiunto al primo strato. La difficoltà è che quando il terzo strato viene aggiunto al secondo strato, c'è anche un terzo strato sotto il secondo strato del primo strato. Infatti, se ci pensi attentamente, puoi capire che c'è un["1"].bambini["2"] sotto a["1"], e il suo valore non solo è uguale a a["2"], ma anche un riferimento sono tutti uguali, ed eseguono a["1"].children.push(a["2"]);. Questo vantaggio si ottiene quando viene eseguito a["3"]={...item, children:[]}, viene eseguito a["2"].children.push(a["3"]), perché è all'interno i dati dell'operazione, quindi anche i posti con lo stesso riferimento (ad esempio, a=b, b.push influenzerà anche a.push) verranno inviati, quindi vedrai a["1"].children["2"] .bambini a["3"]. Questa è la struttura ad albero giusta.
Se ancora non capisci, puoi provare quanto segue:
Come mostrato sopra: b1 è considerato il nodo di primo livello di a1 e la modifica di b1 influenzerà a1. Sebbene quanto sopra sia un ciclo, i riferimenti in ciascun ambito sono gli stessi.
2 4 5 codice sincrono, 3 micro task, 1 macro task.L'unico inconveniente è che verrà stampato 4, ma return 3 non verrà eseguito.
Durante il confronto delle conversioni implicite, l'array chiama il metodo toString.
Devi scriverlo tu. Se non l'hai mai scritto prima, dovrai strapparlo durante il colloquio e molto probabilmente non sarai in grado di strapparlo.Di seguito sono: anti-shake esecuzione immediata ed esecuzione ritardata, throttling esecuzione immediata ed esecuzione ritardata
- function debounce(fn, delay) {
- let timer = null;
- return function (...args) {
- timer && clearTimeout(timer);
- timer = setTimeout(() => {
- fn.apply(this, args);
- }, delay);
- }
- }
-
- function debounce_immediate(fn, delay, immediate = false) {
- let timer = null;
- let flag = true;
- return function (...args) {
- timer && clearTimeout(timer);
- if (immediate) {
- if (flag) {
- fn.apply(this, args);
- flag = false;
- }
- timer = setTimeout(() => {
- flag = true;
- }, delay);
-
- } else {
- timer = setTimeout(() => {
- fn.apply(this, args);
- }, delay);
- }
- }
- }
-
- function throttle(fn, delay) {
- let lastTime = 0;
- let timer = null;
- return function (...args) {
- const nowTime = Date.now();
- if (nowTime - lastTime > delay) {
- fn.apply(this, args);
- lastTime = nowTime;
- }
- }
- }
-
- function throttle_D(func, delayTime) {
- let delay = delayTime || 1000;
- let timer = null;
- return function (...args) {
- if (!timer) {
- timer = setTimeout(function () {
- func.apply(this, args);
- timer = null;
- }, delay);
- }
- }
- }
Ricordati di portare argomenti. La differenza essenziale tra anti-shake e throttling è che l'anti-shake reimposta sempre il timer, mentre il throttling no. Se il throttling viene sempre attivato, verrà eseguito entro un certo intervallo di tempo e verrà eseguito solo una volta. Se l'anti-shake viene attivato per un minuto, verrà eseguito una sola volta (esecuzione immediata o esecuzione ritardata attivata dall'ultimo clic).