JS | סינון אובייקט עם כפילות נתונים
-
יש לי אוביקט JS, כזה:
const inputArray = [ { id: "1", Step: "Step 1", Task: "Task 1", Value: "5" }, { id: "1", Step: "Step 1", Task: "Task 2", Value: "10" }, { id: "1", Step: "Step 2", Task: "Task 1", Value: "15" }, { id: "2", Step: "Step 2", Task: "Task 2", Value: "20" }, { id: "3", Step: "Step 1", Task: "Task 1", Value: "25" }, { id: "3", Step: "Step 1", Task: "Task 2", Value: "30" }, { id: "3", Step: "Step 2", Task: "Task 1", Value: "35" }, { id: "4", Step: "Step 2", Task: "Task 2", Value: "40" } ];
אני רוצה לסנן מהמערך, שיופיע רק רשומה אחת מכל סוג Id.
אבל מצד שני, חשוב לי לשמור על נתון מסוים נגיד מValue, שיופיע הערכים מכל הרשומות גם אלו שלא מוצגים, בהפרדה עם פסיק למשל (או להכניס את זה כתת אוביקט), ויופיע לדוגמה ככה עבור id עם ערך 1:const inputArray = [ { id: "1", Step: "Step 1", Task: "Task 1", Value: "5, 10, 15" } ];
מה הדרך לעשות את זה?
לעבור עם לולאה על כל המערך, ולשמור במשתנה את הערכים וכו', או שיש דרך קלה יותר.אשמח מאד לקבל דוגמת קוד
תודה רבה!
-
מה שאתה רוצה לעשות זה סוג של group by.
כל group by משמעותו לרכז שורות במספר פחות של שורות.
בא נראה קיבוץ קלאסי, מפה https://stackoverflow.com/a/34890276/1271037
הנה הקוד:const inputArray = [ { id: "1", Step: "Step 1", Task: "Task 1", Value: "5" }, { id: "1", Step: "Step 1", Task: "Task 2", Value: "10" }, { id: "1", Step: "Step 2", Task: "Task 1", Value: "15" }, { id: "2", Step: "Step 2", Task: "Task 2", Value: "20" }, { id: "3", Step: "Step 1", Task: "Task 1", Value: "25" }, { id: "3", Step: "Step 1", Task: "Task 2", Value: "30" }, { id: "3", Step: "Step 2", Task: "Task 1", Value: "35" }, { id: "4", Step: "Step 2", Task: "Task 2", Value: "40" } ]; function groupBy(array, key) { return array.reduce(function(rv, curr) { (rv[curr[key]] = rv[curr[key]] || []).push(curr); return rv; }, {}); }; var gr = groupBy(inputArray, "id"); console.log(gr)
הפלט נראה ככה:
{ "1":[{"id":"1","Step":"Step 1","Task":"Task 1","Value":"5"}, {"id":"1","Step":"Step 1","Task":"Task 2","Value":"10"}, {"id":"1","Step":"Step 2","Task":"Task 1","Value":"15"}], "2":[{"id":"2","Step":"Step 2","Task":"Task 2","Value":"20"}], "3":[{"id":"3","Step":"Step 1","Task":"Task 1","Value":"25"}, {"id":"3","Step":"Step 1","Task":"Task 2","Value":"30"}, {"id":"3","Step":"Step 2","Task":"Task 1","Value":"35"}], "4":[{"id":"4","Step":"Step 2","Task":"Task 2","Value":"40"}] }
כלומר יש קבוצת איברים לכל id.
ייתכן מאוד שלצורך שלך זה טוב מאשר ערכים מופרדים בפסיק.
אם לא, אפשר להתקדם מפה עם map על התוצאה האחרונה כדי להתאים את הפלט לאיך שרצית:var gr = groupBy(inputArray, "id"); var proj = Object.keys(gr).map(x => { var curr = gr[x]; return { id: curr[0].id, Step: curr.map(x => x.Step).join(', '), Task: curr.map(x => x.Task).join(', '), Value: curr.map(x => x.Value).join(', ') } });
התוצאה:
[ { id: "1", Step: "Step 1, Step 1, Step 2", Task: "Task 1, Task 2, Task 1", Value: "5, 10, 15" }, { id: "2", Step: "Step 2", Task: "Task 2", Value: "20" }, { id: "3", Step: "Step 1, Step 1, Step 2", Task: "Task 1, Task 2, Task 1", Value: "25, 30, 35" }, { id: "4", Step: "Step 2", Task: "Task 2", Value: "40" } ]
-
@dovid תודה רבה!
כבר כתבתי את זה עם for, אבל השיטה שלך נראית טובה יותר, (האמת אולי לא?,כי אני כן צריך את החלק השני, שיהיה מופרד עם פסיקים, וזו פעולה כפולה, מה אתה אומר?)מה שאני עשיתי, זה משהו כזה:
let oldId; let newArr = []; for (var x of ERR) { if (x.Id !== oldId) { newArr[x.Id] = x; } else { newArr[x.Id]['val'] += ', ' + x.val; } oldId = x.Id; } ERR = newArr;
זה נראה לי לא כ"כ תקין, כי המערך עושה לי בעיות שהוא מתחיל לפעמים עם מספר 50 במקום 0.
אני צריך להמיר את זה למערך רגיל.בכל מקרה, מה לדעתך עדיף?
נ.ב. כמובן שהקוד שלי מתאים רק כשהרשומות מסודרות לפי הסדר של ה ID.
-
ראשית, מאוד חשוב הנקודה שאתה יודע שהשורות לפי סדר הID, זה מאפשר לעשות אחרת וזה חוסך ביצועים.
שנית מה שעשית זה מצויין וטוב יותר, אבל טיפלה מעמיס תחזוקה כמו כל קוד "אישי".
אלא שבקוד שלך טעית והשתמשת באינדקס של מערך, זה בהחלט עושה בעיות.
מערך זה אוסף, לא כדאי אף פעם לעשות שימוש באינדקס של המיקום של האיבר.אני מתקן את הקוד שלך:
let lastRow = { Id: -1 }; let newArr = []; for (var x of ERR) { if (x.Id !== lastRow.Id) { newArr.push(x); } else { lastRow.val += ', ' + x.val; } lastRow = x; } ERR = newArr;