דילוג לתוכן
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום
כיווץ
תחומים

תחומים - פורום חרדי מקצועי

💡 רוצה לזכור קריאת שמע בזמן? לחץ כאן!
רפאלר

רפאל

@רפאל
אודות
פוסטים
186
נושאים
3
קבוצות
0
עוקבים
3
עוקב אחרי
0

פוסטים

פוסטים אחרונים הגבוה ביותר שנוי במחלוקת

  • סגירת יישום לכל המשתמשים במחשב נוכחי (c#)
    רפאלר רפאל
    var current = Process.GetCurrentProcess();
    
    Process.GetProcessesByName(current.ProcessName)
           .Where(p => p.Id != current.Id)
           .ToList()
           .ForEach(p => p.Kill());
    
    current.Kill();
    

    הסבר בקצרה:

    1. קבלת התהליך הנוכחי.
    2. קבלת כל התהליכים הפעילים החולקים את שמם עם התהליך הנוכחי (מלבד התהליך הנוכחי עצמו - אנו זקוקים לשמר אותו בחיים בשלב זה).
    3. סגירת כל התהליכים שבתוצאה.
    4. סגירת התהליך הנוכחי.

    מומלץ להעדיף את השימוש בProcess.CloseMainWindow (המבקש מהתהליך בצורה מנומסת לסיים [Graceful exit]) על פני השימוש בProcess.Kill (המסיים את התהליך מייד, מה שעלול לגרום לתופעות שאינן רצויות) אם כי לא תמיד השימוש בו אפשרי, אולם תמיד ניתן להשתמש בProcess.Kill כFallback במקרה של כישלון:

      if (!p.CloseMainWindow()) p.Kill();
    

    קרדיט: Exit all instances of my app

    ** דוטנט מציעה מספר מחלקות טיימר (כדוגמת system.timers וsystem.threading.timer)


  • חשיבת מפתחים לטווח רחוק..
    רפאלר רפאל

    @katz אמר בחשיבת מפתחים לטווח רחוק..:

    הערך של השנה החדשה עומד על 2,201,010,001

    למי שתהה: שני הספרות הראשונות מייצגות את השנה (השאר בפורמט: חודש, יום, שעה ודקה).

    Date(year: 22, month: 01, day: 01, hour: 00, minute: 01)
    

    אגב שימוש בUnsigned Int היה מאפשר עשרים שנה נוספות.


  • הרצת callback רק עם התוצאה של הקריאה האחרונה
    רפאלר רפאל

    ביכולתך לממש Debouncing כך:

    function returnOnce(func) {
        let counter = 0;
        return async (...args) => {
            const id = ++counter;
            await new Promise(x => setTimeout(x, 300));
            if (counter > id) return;
            const result = await func(...args);
            if (counter === id) {
                return result
            }
        };
    }
    

    Reactive programming

    אישית הייתי משתמש בRxJs עבור המשימה, הרבה יותר אפשרויות, פחות קוד לתחזוק,

    fromEvent(input, 'keyup')
        .pipe(
            debounceTime(300),
            distinctUntilChanged(),
            switchMap(e => func(e.target.value))
        )
        .subscribe(result => updateUi(result))
    

    בדוגמא למעלה אנו יוצרים Observable שמאזין לאירוע keyup של התבת טקסט,
    לאחר מכן אנחנו מוסיפים אופרטורים (באמצעותם ניתן לקבוע מה יתרחש בשעה שערך יוחזר) באמצעות המתודה Pipe:

    1. DebounceTime
      עבור כל ערך שחוזר, המתן X מילי שניות, במידה ובמהלך הזמן הזה ערך חדש מופיע, התעלם מהערך הנוכחי, וחזור על התהליך שוב, במידה והזמן חלף ללא הופעת ערך חדש, העבר את הערך לאופרטור הבא.

    2. DistinctUntilChanged
      התעלם מהערך הנוכחי במידה והוא זהה לערך הקודם, במידה ולא, העבר את הערך לאופרטור הבא.

    3. SwitchMap
      האופרטור מקבל מתודה שמקבלת את הערך שחזר מהאופרטור הקודם כפרמטר ומחזירה Observable/Promise, המתודה תרוץ עבור כל ערך שחוזר, הObservable/Promise הפנימיים יתבטלו במידה והם עדיין רצים בשעה שערך חדש מופיע (עבור Promise אין לדבר משמעות מלבד התעלמות מהתוצאה).

    Promise vs Observable

    1. Observable אינו מוגבל להחזרת ערך בודד.
    2. Promise רץ ברגע שהוא נוצר, לעומת Observable שירוץ רק במידה ונרשם אליו באמצעות Subscribe (הדבר אינו נכון עבור Hot Observable אולם השימוש בו נדיר יותר ונתעלם ממנו לצורך העניין).

    לסיכום

    אני משוכנע שידע בתכנות ריאקטיבי, הופך אותך למתכנת טוב יותר, במיוחד בפיתוח ממשקים, בו יש צורך לטפל בstream של אירועים בצורה אסינכרונית.


  • Caddy Web-Server
    רפאלר רפאל

    Caddy נחשב איטי בצורה משמעותית מNginx.

    ואם בReverse proxy servers עסקינן, לאחרונה התוודעתי דרך הבלוג של מיקרוסופט לפרויקט חדש של מיקרוסופט בשם Yarp, (ר"ת של Yet Another Reverse Proxy) למרות השם המטעה מדובר בספרייה שמספקת כלים לבניית שרתי פרוקסי מהירים עבור ישומים של Net., היא מבוססת על העקרונות של ASP.NET ומותאמת לpipeline של ASP.NET, מה שמבדיל אותה משרתי פרוקסי אחרים, זה הצורה בו היא משתלבת בסביבה של ASP.NET מה שמאפשר יכולות שלא היו קיימות עד עתה עבור מפתחי Asp.

    לדוגמא: באמצעות MIddleware ניתן ליצור לוגים, להגדיר האם בקשות יועברו הלאה לשרת נוסף או לא, ואם כן לאיזה שרת, ולהוסיף לוגיקה מותאמת אישית לפיצרים כמו טיפול בשגיאות ונסיונות חוזרים.

    למעוניינים להלן הGet started שלהם.


  • אתחול אובייקט ב-TS.
    רפאלר רפאל

    @yyy כדאי להימנע מיצירת מופעים עבור מחלקות בצורה ליטרלית משום שהPrototype שלהם יהיה זהה לזה של Object.

    ההשלכות המצערות:

    • האובייקט לא יכיל את המתודות והProperties של המחלקה.
    • ההצבות (בתוך הבנאי ומחוצה לו) לא יתבצעו (התגלית שהערך של השדה Y במופע שיצרת יהיה זהה לundefined לא אמורה להיות מפתיעה במיוחד כעת).
    • השימוש בisPrototypeOf ו instanceof לא יניב את התוצאה הרצויה (וכן כל המתודות שבPrototype).

    מסקנה:

    • היכן שהשימוש בObject literal נחוץ (ומתאפשר) השתמש בInterface לציון הType (עקב הצורך בערך דיפולטיבי עבור Y האפשרות לא רלוונטית עבורך)
    • צור מופעים עבור מחלקות באמצעות הבנאי:
    class ZeroYCoordinate {
      public readonly y: number = 0;
      constructor(public x: number) { }
    }
    
    const points = [new ZeroYCoordinate(4)]
    

    ** שינוי Prototype אפשרי באמצעות השימוש בsetPrototypeOf, אם כי הדבר אינו מהווה פתרון מקיף לכל הבעיות שציינתי.


  • סתם סקרנות, מה הקשר בין פייפאל לסינגפור?
    רפאלר רפאל

    @אביי פייפאל היא חברה אמריקאית הרשומה בארצות הברית מאז ומעולם.
    המטה הבין לאומי שלה שוכן בסינגפור.
    השרות בכל מדינות אסיה מסופק ע"י PayPal Pte. Ltd שהיא אכן רשומה בסינגפור.
    השרות בשאר העולם אינו מסופק ע"י החברה הנ"ל.


  • קבצים סטטיים ב ASP Core
    רפאלר רפאל

    שים לב שהMSBuild item המכונה Folder הוא משתנה שרירותי המייצג קבצים (באותה מידה יכולת להשתמש עם תג בשם NiceFolder) כל עוד לא הItem אינו מועבר כפרמטר לTask כלשהוא, לא יתרחש עם הקבצים שהוא מייצג דבר.

    בניגוד ל:

    • Compile
    • Content (האפשרות הרצויה במקרה שלך)
    • None
    • EmbeddedResource ועוד.
      המייצגים Build Actions בMSBuild
       
       
      לכל Framework בNet. יש Target המייצג את פעולת הBuild (הTarget הנ"ל אינו מופיע בקובץ הפרויקט אולם ניתן להתייחס אליו בתזמון Targets נוספים, למשל לMSBuild item בשם Page יש משמעות מיוחדת רק בBuild של WPF), לMSBuild item בשם Folder אין כל משמעות בBuild של Asp.
       
      לשם ההדגמה, להלן Target המכיל שלושה Tasks (המשימה: ביצוע Build של פרויקט כלשהוא והעתקת התוצאה לנתיב שרירותי כלשהוא במערכת הקבצים)
    1. MSBuild מייצג Build של קובץ MSBuild אחר (במקרה זה אנחנו מבצעים Build לפרויקט X)
    2. MakeDir מייצג Task היוצר תיקייה (אנחנו משתמשים בPropertyGroup בשם Destination כדי לקבוע את היעד)
    3. Copy מייצג Task המעתיק קבצים (אנחנו משתמשים בItemGroup השרירותי MySourceFiles על מנת לקבוע את הקבצים שיועתקו (במקרה זה התוצאה של משימה 1) ובPropertyGroup בשם Destination על מנת לקבוע את היעד)
    <Target Name="BuildProjectAndCopyFiles" AfterTargets="BeforeBuild">
    	<PropertyGroup>
    		<MyDestination>\SomePath</MyDestination>
    	</PropertyGroup>
    
    	<ItemGroup>
    		<MySourceFiles Include="ProjectName\bin\$(Platform)\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\**\*.*" />
    	</ItemGroup>
    
    	<MSBuild Projects="ProjectName\ProjectName.csproj" Targets="Build" Properties="Configuration=$(Configuration);Platform=$(Platform)"/>
    	<MakeDir Directories="$(MyDestination)" />
    	<Copy SourceFiles="@(MySourceFiles)" DestinationFolder="$(MyDestination)\%(RecursiveDir)" SkipUnchangedFiles="true" />
    </Target>
    

    כאן ניתן למצוא את הרשימה המלאה של הTasks המובנים בMSbuild
     
     

    לסיכום:

    הBuild Action הרצוי עבור קבצים סטטים הוא Content, הקבצים יועתקו לשורש תיקיית היעד תוך שמירה על ההיררכיה המקורית:

    <ItemGroup>
       <Content Include="files\**" />
    </ItemGroup>
    

    הקבצים בתיקיית files יהיו זמינים בנתיב הבא:

    new Uri("files/somefile.xyz")
    

    ** שים לב שהתהליך הנ"ל מתבצע בASP אוטומטית עבור התיקייה wwwroot.

    ** כאן ניתן הסבר בהרחבה כיצד לחשוף קבצים סטטים מחוץ לתיקיית wwwroot לבקשות HTTP באמצעות ASP.


  • איך לתעד RESTfull
    רפאלר רפאל

    Swagger זה מימוש של התקן המתקרא OpenAPI (גירסה מס' 3), התקן מיועד עבור תיעוד REST APIs.
    Swagger גם מספקת כלים אוטומטיים ליצור את התיעוד וכלים חזותיים (Middlewares) לצפות בתיעוד (התקן כולל קובץ JSON\YAML בלבד) בנוסף לאפשרות לבצע קריאה לכל אחד מהEndpoint החשופים בתיעוד, עם הפרמטרים וההדרים הדרושים.


  • אבטחת מידע
    רפאלר רפאל

    @mekev אמר באבטחת מידע:

    איך הויזואל סטודיו שולח את המידע

    ויזואל סטודיו אינו מתקשר עם מסד הנתונים, התוכנה שלך היא שעושה זאת.
    בחירה בחיבור מאובטח TLS מתאפשרת בעת יצירתו ע"י הגדרת הפרמטר Encrypt לTrue בConnection String.

    var builder = new SqlConnectionStringBuilder
    {
    	DataSource = "ServerName",
    	InitialCatalog = "DatabaseName",
    	UserID = "UserName",
    	Password = "UserPassword",
    	Encrypt = true
    };
    
    var connection = new SqlConnection(builder.ConnectionString);
    

    כמובן שעליך לטפל ברמת המסד ביצירת תעודת אבטחה שתוכר ע"י הלקוח (ע"י יצירת תעודה חתומה ע"י CA כדוגמת Let’s Encrypt או ע"י יצוא התעודה והתקנה אצל הלקוח, לחלופין ניתן לבטל את האימות ע"י הוספת TrustServerCertificate=True לConnection String [לא מומלץ])
    כמו כן יש לאפשר במסד כניסת חיבורים מאובטחים.


  • תוספים שימושיים לVSC
    רפאלר רפאל

    ההשלמה האוטומטית מבוססת הבינה מלאכותית המובנית בVisual Studio 2022 שהזכיר @dovid תומכת גם בTypeScript/JavaScript (הרשימה המלאה למטה) בנוסף Visual Studio 2022 מציע מעלות ואפשרויות רבות נוספות עבור הפיתוח בTypeScript/JavaScript (כפי שניתן לראות כאן) מה שהופך אותו לIDE מצויין גם עבור שפות אלו.

    עם זאת משתמשי VSC גם יכולים להנות מאותה השלמה אוטומטית באמצעות הורדת התוסף הפופולארי Visual Studio IntelliCode, התוסף ממוקם במקום השמיני ברשימת התוספים הפופולריים ביותר של VSC עם מעל 17 מיליון הורדות.

    השפות הנתמכות ע"י Visual Studio IntelliCode:

    1. Python
    2. TypeScript/JavaScript
    3. Java

    השפות הנתמכות ע"י Visual Studio 2022 AI-based IntelliCode:

    1. C#
    2. C++
    3. TypeScript/JavaScript
    4. XAML
    5. Visual Basic

  • scss ייבוא משתנים לקומפוננטים
    רפאלר רפאל

    @chagold עליך לציין שאתה מעוניין בתחביר SCSS

    <style lang="scss">
      @import "./_variables.scss";
    </style>
    

  • עזרה | סקריפט באש למחיקת קבצים מורכבת
    רפאלר רפאל

    @yossiz אמר בעזרה | סקריפט באש למחיקת קבצים מורכבת:

    php << EOF
    // your code here
    EOF
    

    למי שתהה לגבי התחביר מדובר בHere Document המהווה כלי שימושי בין השאר להצבת מחרוזות מרובות שורות לתוך משתנים, קבצים או Pipes.

    התחביר:

    [COMMAND] <<[-] 'DELIMITER'
      HERE-DOCUMENT
    DELIMITER
    

     

    הסבר התחביר בקצרה:

    COMMAND שם הקובץ\Pipe
    [-]>> (Redirection Operator) הפנית התוכן של הHERE-DOCUMENT לStdin של הפקודה שקדמה לאופרטור, באנלוגיה לInput Redirection העושה שימוש בסימן "קטן מ" (>) בודד: cat < file (וזאת מכיוון שהShell מתייחס לHERE-DOCUMENT כקובץ בפני עצמו [Stream Literal]). (הוספת מינוס לאופרטור אופציונלית ותגרום לShell להתעלם מטאבים פותחים בשורות הקלט)
    DELIMITER מחרוזת שתשמש כאינדיקציה לסיום קבלת הקלט (כדי שתתפרש כך, על המחרוזת להופיע בקלט כשורה בפני עצמה ללא רווחים פותחים או סוגרים)
    HERE-DOCUMENT הקלט (מחרוזות, משתנים וכן כל סוג אחר של Input)

     

    דוגמא

    cat << hello
    

    העבר לcat את הקלט שתקבל, סיים את קבלת הקלט כשהמילה hello מופיעה.


  • כת מיסיונרית נכשלה שוב בניסיון המי יודע כמה להעביר אותי על דתי
    רפאלר רפאל

    @ארכיטקט
    מוטלת עליך המשימה המורכבת להסביר את העובדה שישנם יותר אנשים שמשתמשים באותן מילות גנאי (ולפעמים אף מסלימים צפונה) דווקא כלפי אנגולר.
    היתכן שרק אנחנו היחידים (יחסית) זכינו להתקרב ולהבחין באור? יתכן מאד שכן.

    אך מצד שני ניתן להסביר את הרתיעה שלי ושלך בעובדה שהתרגלנו למשהו אחר, אולם המשהו האחר הזה לאו בהכרח טוב יותר אבסולוטית.
    התרגלנו לנוכחותה של סביבה דעתנית שמנהלת את החיים:
    סביבה שמכתיבה (ולפעמים בצורה דיקטטורית ואכזרית) דרך ברורה,
    עוזרת לנו להימנע מטעויות מיותרות,
    מעירה לנו (ובאופן עדין במיוחד) כשאנחנו סוטים מהחזון של מהנדסיה.

    אולם עלינו לזכור את כל התינוקות שנשבו שהשארנו מאחור, שמעולם לא ראו בדבר יתרון, אדרבה, חוסר הפשטות של הפיתוח והבריונות של C# וAngular הבריחה אותם, ולמקום רחוק מאוד.

    לסיכום:
    אני נאלץ להודות שהזדהיתי עם כל מילה שכתבת (לפני מספר ימים מישהו פה העלה פוטס שעסק בVue, סקירה קצרה על הFramework עם דוגמא קטנה, גרמה לי לזעזוע לא קל, ולמעשה נשגב מבינתי כיצד Angular הגדולה סיימה על אותו מדף יחד עם Vue (עבדתי תקופה קצרה בחברה שפיתחה בReact עם Redux, לא סבלתי שם יותר מדי, כך שמאוד ייתכן שאם הייתי מתחיל עם React הייתי נשאר שם רח"ל).
    כשאני מסתכל על המוצרים של Microsoft כדוגמת C# .NET, Visual Studio אני משתאה כל פעם מחדש על כך שאנשים לא עוזבים את הכל ובאים אל האור. את השאלה הזו ניסיתי ליישב בפוסט הנוכחי.


  • הרצת callback רק עם התוצאה של הקריאה האחרונה
    רפאלר רפאל

    @yossiz אמר בהרצת callback רק עם התוצאה של הקריאה האחרונה:

    נעלבתי

    גם לי לא לקח יום אחד להבין איך הכל עובד, ואני בטוח שלך יקח פחות.

    @yossiz אמר בהרצת callback רק עם התוצאה של הקריאה האחרונה:

    והוא מחזיר מיד את הפרומיס בצורה סינכרונית

    בהחלט, אבל שים לב להבדלים בין:

    • Map מיועד למיפוי ערך פשוט
    • SwitchMap יבטל את הרישום לObservable הפנימי הקיים וייצור Observable עבור הערך החדש
    • MergeMap ייצר Observable פנימי עבור הערך החדש, בלי לבטל את הObservable הפנימי, כך שאין סוף Observables פנימיים יכולים להיות פעילים במקביל (אפשר להגביל את הכמות).
    • ExhaustMap יתעלם מערכים חדשים כל עוד שהObservable הפנימי פעיל.
    • ConcatMap ימתין שהObservable הפנימי יושלם לפני שיצור Observable פנימי נוסף, הערכים נשמרים בBuffer פנימי.

    להלן יישום קטנטן שמציג Countdown כתוצאה להזנה לתוך תבת טקסט, ובסיום מציג מערך המכיל את האותיות המרכיבות את הטקסט, הקוד מראה בבירור שכל פעם שמגיע ערך חדש, הObservable הפנימי הקודם יתבטל והטיימר יתאפס.

     
     

    תרשים ציר זמן המתאר את ההבדלים בין הMaps השונים:

    • $Source מתאר את הstream המקורי.
      הכחול מייצג את הערך הראשון מהstream החיצוני
      הצהוב את השני
      הירוק את השלישי
    • $Target מייצג את הstream הפנימי (כל איבר מהstream החיצוני ימופה לstream פנימי)

    באיור הבא כל איבר בstream המקורי "משתכפל" כמספר הערכים שהstream הפנימי פלט (בכפוף למדיניות של האופרטורים הנ"ל):
     
    כיתוב בבעיות טעינה


  • קבלת טקסט של דף אינטרנט
    רפאלר רפאל

    @משה-כהן345

    1. כדאי שתתחיל להבין את הסיבה למגבלה הזו.
    2. אלא א"כ אתה אתה בעל השרת אין הרבה מה לעשות (וטוב שכך) חוץ מלהשתמש עם שרת Proxy, או לחלופין להשבית את ההגבלה של CORS בדפדפן אם כי אני מניח שהפתרון השני לא בדיוק יעזור לך.

  • חיפוש ( {{טקסט}} ) במחרוזת והחלפתם.
    רפאלר רפאל

    @ש-ב-ח עזוב את העובדה שלמילה Map יש משמעות, אנשים שנתקלים בMap מצפים להתנהגות מסויימת, במילים אחרות: מעבר לפונקציונליות של הקוד, למוסכמות יש ערך לא פחות חשוב (אפילו אם ההתנהגות של שני המתודות היו זהות).


  • getTime אינו פונקציה
    רפאלר רפאל

    @dovid התשובה שלילית, הקוד המיוצר זהה כמעט לחלוטין למקור, למעט מקרים ספורים (למשל הOptional operator לפני שהיה זמין בJS).

    מאמר שהתפרסם בNCC Group תחת הכותרת:
    ?Does TypeScript Offer Security Improvements Over JavaScript
    קובע באופן נחרץ:

    מה אנחנו מרוויחים מהשימוש ב-TypeScript מבחינת בטיחות? התשובה היא אפס. למעשה אם כבר, השימוש בTypeScript רק גורע מהבטיחות מכיוון שהוא מעניק לנו תחושת שווא של טיפוסיות קשוחה ובדיקת סוגים שלא קיימות בפועל בזמן הריצה.

    שימושית כל שתהיה בזמן הכתיבה, אין שום יתרון לשימוש בזמן הריצה.


  • getTime אינו פונקציה
    רפאלר רפאל

    @odeddvir ניתן לטפל בעניין ע"י שימוש נכון בתחביר.

    אפשרות אחת היא שימוש בUnion type, לדוגמא string | Date מייצג ערך שיכול להיות Date או String.

    interface Person {
      name: string;
      dob: string | Date;
    }
    

    Union type מאפשר לך לגשת למאפיינים שמשותפים לכל הסוגים המרכיבים את הUnion ללא כל בעיה, אולם כדי לגשת למאפייינים היחודיים לאחד מהסוגים המרכיבים את הUnion נדרשת המרה של הUnion לסוג הספיציפי הדרוש ע"י בדיקת JS שהסוג אכן תואם והמהדר של Typescript ידייק וישנה את הסוג המוצהר (הUnion) לסוג הספיציפי, לדוגמא:

      person.dob.getDay() // Error: getDay does not exist on type string
    
      if (typeof person.dob === 'object') {
        person.dob.getDay() // Date בתוך התנאי הסוג הוא 
      }
    

    דרך נוספת היא ליצור שני מודלים, הראשון יייצג את הערך היוצא לשרת (Outbound), והשני יייצג את הערך שחוזר מהשרת (Inbound) לדוגמא:

    interface PersonBase {
      name: string;
    }
    
    interface ResponsePerson extends PersonBase {
      dbo: string;
    }
    
    class Person implements PersonBase {
      constructor(public name: string, public dbo: Date) { }
    
      public static fromPersonResponse({ name, dbo }: ResponsePerson): Person {
        return new Person(name, new Date(dbo))
      }
    }
    

  • date ב-input, ו-ngModel אנגולרי
    רפאלר רפאל

    תיישם את זה כך:

    <input  type="date" [ngModel]="CLS.BirthDate | date:'yyyy-MM-dd'" (ngModelChange)="CLS.BirthDate = $event"/>
    

    הפתרון הוא לחלק את הTwo-ways binding לשניים: One-way binding ו Event Binding.
    למעשה [(ngModel)] כולל את שניהם, [ ] מייצג One-way binding, ו ( ) מייצג Event binding.
    הסיבה שאינך יכול להשתמש עם התחביר המשולב [( )] היא השימוש בDatePipe (אנגולר לא מאפשרת שימוש בPipes בשילוב עם Two-ways binding)

    ועוד Convention קטן שלא הרבה יודעים:
    כל Output בעל שם דומה ל Input קיים, בתוספת המילה Change יכול לשמש עבור Two-ways binding ללא כל הגדרה נוספת.


  • החלפת הקלדה לעברית.
    רפאלר רפאל

    @אבי-203
    אני חושב שהקוד תקין.

    class LayoutConvertor {
      static convert(str) {
        return str.replace(/./g, x => this.#lookup.get(x.toLowerCase()) ?? x)
      }
    
      static #lookup = new Map([
        ["q", "/"],
        ["w", "'"],
        ["e", "ק"],
        ["r", "ר"],
        ["t", "א"],
        ["y", "ט"],
        ["u", "ו"],
        ["i", "ן"],
        ["o", "ם"],
        ["p", "פ"],
        ["[", "]"],
        ["{", "}"],
        ["]", "["],
        ["}", "{"],
        ["\\", "\\"],
        ["|", "|"],
        ["a", "ש"],
        ["s", "ד"],
        ["d", "ג"],
        ["f", "כ"],
        ["g", "ע"],
        ["h", "י"],
        ["j", "ח"],
        ["k", "ל"],
        ["l", "ך"],
        [";", "ף"],
        [":", ":"],
        ["'", ","],
        ["\"", "\""],
        ["z", "ז"],
        ["x", "ס"],
        ["c", "ב"],
        ["v", "ה"],
        ["b", "נ"],
        ["n", "מ"],
        ["m", "צ"],
        [",", "ת"],
        ["<", ">"],
        [".", "ץ"],
        [">", "<"],
        ["/", "."],
        ["?", "?"]
      ]);
    }
    
  • 1 / 1
  • התחברות

  • אין לך חשבון עדיין? הרשמה

  • התחברו או הירשמו כדי לחפש.
  • פוסט ראשון
    פוסט אחרון
0
  • דף הבית
  • קטגוריות
  • פוסטים אחרונים
  • משתמשים
  • חיפוש
  • חוקי הפורום