امین محمدزاده
4 سال پیش توسط امین محمدزاده مطرح شد
16 پاسخ

تبدیل یک آرایه با جاوا اسکریپت به یک فرمت دلخواه

سلام
من یه آرایه ای دارم که میخوام پارامترهای اون با نمونه فرمتی که نوشتم نشون داده بشه.
من این کار رو با php انجام میدم ولی همون الگو رو با جاوااسکریپت میبرم جلو نتیجه ای که میخوام رو نمیده
داده ای که به صورت json هست :

'{"variants": [{"options": [{"name": "red"},{"name": "blue"},{"name": "green"},{"name": "yellow"}]},{"options": [{"name": "small"},{"name": "medium"},{"name": "large"}]},{"options": [{"name": "i"},{"name": "ii"},{"name": "iii"}]}]}'

کد php :

function getVariants($obj)
    {
        $variant = array_shift($obj["variants"]);
        $results = array();
        foreach($variant["options"] AS $k=>$v)
        {
            if(count($obj["variants"]) > 0)
            {
                $sub = $this->getVariants($obj);
                foreach($sub AS $sub_v)
                {
                    $results[] = $v["name"]." ".$sub_v;
                }
            }
            else
            {
                $results[] = $v["name"];
            }
        }
        return $results;
    }
var_dump(getVariants(json_decode($v,true)));

نتیجه ای که کد php میده و فرمت درست هم همین هست :

array:36 [▼
  0 => "red small i"
  1 => "red small ii"
  2 => "red small iii"
  3 => "red medium i"
  4 => "red medium ii"
  5 => "red medium iii"
  6 => "red large i"
  7 => "red large ii"
  8 => "red large iii"
  9 => "blue small i"
  10 => "blue small ii"
  11 => "blue small iii"
  12 => "blue medium i"
  13 => "blue medium ii"
  14 => "blue medium iii"
  15 => "blue large i"
  16 => "blue large ii"
  17 => "blue large iii"
  18 => "green small i"
  19 => "green small ii"
  20 => "green small iii"
  21 => "green medium i"
  22 => "green medium ii"
  23 => "green medium iii"
  24 => "green large i"
  25 => "green large ii"
  26 => "green large iii"
  27 => "yellow small i"
  28 => "yellow small ii"
  29 => "yellow small iii"
  30 => "yellow medium i"
  31 => "yellow medium ii"
  32 => "yellow medium iii"
  33 => "yellow large i"
  34 => "yellow large ii"
  35 => "yellow large iii"
]

همین کد php رو تبدیل به جاوااسکریپت میکنم :

getVariants(obj) {
        let variant = obj['variants'].shift();
        let results = [];
        for(let j in variant['options']) {
            if(obj['variants'].length > 0) {
                let sub = getVariants(obj);
                for (let i in sub) {
                    results.push(variant['options'][j]['name']+" "+sub[i]);
                }

            } else {
                results.push(variant['options'][j]['name']);
            }
        }

        return results;
    }
console.log(getVariants(JSON.parse(array)))

نتیجه ای که برمیگردونه اینه :

["red small i", "red small ii", "red small iii", "red medium", "red large", "blue", "green", "yellow"]

ممنون میشم از دوستان بتونه کمک کنه


ثبت پرسش جدید
میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش آپدیت شد
0

تابع رو بصورت پویا و به روش بازگشتی نوشتم.
مثال ها رو هم امتحان کردم، همگی درست هستند.

<!-- seprate arrays from object / create array of arrays -->
        function seprateArr(base) {
            let baseArr = [];
            for (let i = 0; i < base['variants'].length; i++) { 
                baseArr[i] = new Array();// array of arrays
            } 

            for(var i = 0; i < base['variants'].length; i++) {
                for(var j = 0; j < base['variants'][i]['options'].length; j++) {
                    baseArr[i].push(base['variants'][i]['options'][j]['name']);
                }
            }
            return baseArr;         
        }
        console.log(seprateArr(base));

        <!-- combination dynamic number arrays -->
        function combinationArr(baseArray) {
            let helpArr = [];

            if (baseArray.length == 1) return baseArray[0];
            else if (baseArray.length == 2) {
                for(var i = 0; i < baseArr[0].length; i++) {
                    for(var j = 0; j < baseArr[1].length; j++) {
                        helpArr.push(baseArr[0][i] + " " + baseArr[1][j]);                      
                    }
                }
                return helpArr;
            } else {
                let x = baseArray.pop();
                let y = combinationArr(baseArray);

                for(var i = 0; i < y.length; i++) {
                    for(var j = 0; j < x.length; j++) {
                        helpArr.push(y[i] + " " + x[j]);                        
                    }
                }
                return helpArr;
            }
        }

امین محمدزاده
تخصص : برنامه نویسی وب - Laravel
@amin.webdesign 4 سال پیش مطرح شد
0

کیست مرا یاری کند؟!


مجید درویش نژاد
تخصص : React js and native Developer
@majidmagic 4 سال پیش آپدیت شد
0

از کلاس Map و متد set استفاده کن
()let results = new Map
اونجایی هم که داری push میکنی به جاش ست کن (variant['options'][j]['name'])results.set
البته ست رو فکر کنم بد نوشتم باهاش یکم ور برو دستت میاد


امین محمدزاده
تخصص : برنامه نویسی وب - Laravel
@amin.webdesign 4 سال پیش مطرح شد
0

@majidmagic
خیلی ممنون از پاسخت ولی فعلا با یه روش دیگه بردم جلو چون زمان زیادی ندارم. ان شاالله حتما یه وقت دیگه از روشی که فرمودید استفاده کردم بازخورد رو همینجا منتشر میکنم.


میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش مطرح شد
0

ابتدا مسئله رو بصورت ساده حل می کنیم:

        let array1=["red","blue","green", "yellow"];
        let array2=["small","medium","large"];
        let array3=["i","ii","iii"];

        let simpleComb = [];

        for(var i = 0; i < array1.length; i++) {
            for(var j = 0; j < array2.length; j++) {
                for(var k = 0; k < array2.length; k++) {
                    simpleComb.push(array1[i] + " " + array2[j] + " " + array3[k]);
                }
            }
        }

        console.log(simpleComb);

میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش آپدیت شد
0

با توجه به راه حل ساده ی بالا، کافیست روی شی مربوطه، ابتدا جداسازی سه آرایه رو صورت دهیم و سپس به روش بالا آنها را باهم ترکیب کنیم.

بخش اول: جداسازی

let base = {"variants": [
                                    {"options": [{"name": "red"},{"name": "blue"},{"name": "green"},{"name": "yellow"}]},
                                    {"options": [{"name": "small"},{"name": "medium"},{"name": "large"}]},
                                    {"options": [{"name": "i"},{"name": "ii"},{"name": "iii"}]}
                                ]};

        <!-- let arr1 = base['variants'][0]['options'][0]['name'];       -->
        <!-- console.log(arr1); -->

        <!-- seprate 3 arrays from object / create array of arrays -->
        let baseArr = [];
        for (let i = 0; i < base['variants'].length; i++) { 
            baseArr[i] = new Array();// array of arrays
        } 

        for(var i = 0; i < base['variants'].length; i++) {
            for(var j = 0; j < base['variants'][i]['options'].length; j++) {
                baseArr[i].push(base['variants'][i]['options'][j]['name']);
            }
        }
        console.log(baseArr);

میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش مطرح شد
0

ادامه راه حل بالا:
بخش دوم: ترکیب آرایه ها باهم

<!-- combination 3 arrays -->
        var hardComb = [];
        for(var i = 0; i < baseArr[0].length; i++) {
            for(var j = 0; j < baseArr[1].length; j++) {
                for(var k = 0; k < baseArr[2].length; k++) {
                    hardComb.push(baseArr[0][i] + " " + baseArr[1][j] + " " + baseArr[2][k]);
                }
            }
        }

        console.log(hardComb);

میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش مطرح شد
0

و این هم همه ی کدها بصورت یکجا و در کنار هم:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>three Arrays combinations</title>
    <style>

    </style>
</head>
<body>
    <h1> look console!! </h1>

    <script>
        let array1=["red","blue","green", "yellow"];
        let array2=["small","medium","large"];
        let array3=["i","ii","iii"];

        let simpleComb = [];

        for(var i = 0; i < array1.length; i++) {
            for(var j = 0; j < array2.length; j++) {
                for(var k = 0; k < array2.length; k++) {
                    simpleComb.push(array1[i] + " " + array2[j] + " " + array3[k]);
                }
            }
        }

        console.log(simpleComb);

        let base = {"variants": [
                                    {"options": [{"name": "red"},{"name": "blue"},{"name": "green"},{"name": "yellow"}]},
                                    {"options": [{"name": "small"},{"name": "medium"},{"name": "large"}]},
                                    {"options": [{"name": "i"},{"name": "ii"},{"name": "iii"}]}
                                ]};

        <!-- let arr1 = base['variants'][0]['options'][0]['name'];       -->
        <!-- console.log(arr1); -->

        <!-- seprate 3 arrays from object / create array of arrays -->
        let baseArr = [];
        for (let i = 0; i < base['variants'].length; i++) { 
            baseArr[i] = new Array();// array of arrays
        } 

        for(var i = 0; i < base['variants'].length; i++) {
            for(var j = 0; j < base['variants'][i]['options'].length; j++) {
                baseArr[i].push(base['variants'][i]['options'][j]['name']);
            }
        }
        console.log(baseArr);

        <!-- combination 3 arrays -->
        var hardComb = [];
        for(var i = 0; i < baseArr[0].length; i++) {
            for(var j = 0; j < baseArr[1].length; j++) {
                for(var k = 0; k < baseArr[2].length; k++) {
                    hardComb.push(baseArr[0][i] + " " + baseArr[1][j] + " " + baseArr[2][k]);
                }
            }
        }

        console.log(hardComb);
    </script>
</body>
</html>

امین محمدزاده
تخصص : برنامه نویسی وب - Laravel
@amin.webdesign 4 سال پیش مطرح شد
1

@milad
سلام. ممنون از پاسختون ولی مسئله اصلی آبجکت من اینه که داینامیک هست و تعداد سطر و ستون یکسانی نداره که بخوایم براش تعداد for مشخصی بنویسیم. میتونه فقط یک ردیف داشته باشه یا بیشتر از اون که بر اساس تعداد ردیف ها و تعداد ستون های هر ردیف خروجی داینامیک بده ولی کد شما برای حالت استاتیک هست.


میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش مطرح شد
0

خواهش میکنم.
به چه صورت پویا هستش؟
در اینجا سه تا آرایه بودش. / منظورتون اینه که تنها تعداد آرایه های درونی متغیر هستش؟ یعنی یک یا دو یا سه یا 4 تا یا 5 تا و ... باشه؟

یا اینکه منظورتون پویایی بیشتری بصورت درونی هستش؟
لطفا لااقل سه مثال دیگر را هم اینجا بنویسید.


امین محمدزاده
تخصص : برنامه نویسی وب - Laravel
@amin.webdesign 4 سال پیش مطرح شد
1

ما توی آبجکتمون یه سری ردیف ها داریم که با options مشخص شده یعنی میتونه فقط یه ردیف داشته باشه مثل :

let base = {"variants": [
                                    {"options": [{"name": "red"},{"name": "blue"},{"name": "green"},{"name": "yellow"}]}
                                ]};

یا دو تا ردیف مثل :

let base = {"variants": [
                                    {"options": [{"name": "red"},{"name": "blue"},{"name": "green"},{"name": "yellow"}]},
                                    {"options": [{"name": "small"},{"name": "medium"},{"name": "large"}]}
                                ]};

یا بیشتر یعنی توی تعداد ردیف ها و مقادیر هر ردیف محدودیتی لحاظ نشه. یعنی مقدار هر ردیف هم میتونه از یک تا هر چند تا که بود متغیر باشه. یعنی یه ردیف میتونه یه مقدار داشته باشه و یه ردیف مثلا 10 تا
البته کد شما از لحاظ تعداد مقادیر هر ردیف اوکی هست و مسئله اصلی تعداد متغیر هر ردیف یعنی همون مقدار options هست.
کدی هم که خودم توی متن سوال گذاشتم اگه دقت کنید فراخوانی یه تابع درون هر حلقه هست. یعنی برای این حالت ردیف نامحدود از روش توابع تودرتو استفاده میشه که این مسئه رو توی php اوکی کردم ولی توی جاوااسکریپت این مسئله درست عمل نمیکنه که البته فکر کنم مشکل از shift کردن در ردیف های آبجکت رخ میده چون این عمل توی php درست کار میکنه که احتمالا این روشshift کردن آرایه شاید توی جاوااسکریپت با روش دیگه ای عمل میکنه.


میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش آپدیت شد
0

تابع رو بصورت پویا و به روش بازگشتی نوشتم.
مثال ها رو هم امتحان کردم، همگی درست هستند.

<!-- seprate arrays from object / create array of arrays -->
        function seprateArr(base) {
            let baseArr = [];
            for (let i = 0; i < base['variants'].length; i++) { 
                baseArr[i] = new Array();// array of arrays
            } 

            for(var i = 0; i < base['variants'].length; i++) {
                for(var j = 0; j < base['variants'][i]['options'].length; j++) {
                    baseArr[i].push(base['variants'][i]['options'][j]['name']);
                }
            }
            return baseArr;         
        }
        console.log(seprateArr(base));

        <!-- combination dynamic number arrays -->
        function combinationArr(baseArray) {
            let helpArr = [];

            if (baseArray.length == 1) return baseArray[0];
            else if (baseArray.length == 2) {
                for(var i = 0; i < baseArr[0].length; i++) {
                    for(var j = 0; j < baseArr[1].length; j++) {
                        helpArr.push(baseArr[0][i] + " " + baseArr[1][j]);                      
                    }
                }
                return helpArr;
            } else {
                let x = baseArray.pop();
                let y = combinationArr(baseArray);

                for(var i = 0; i < y.length; i++) {
                    for(var j = 0; j < x.length; j++) {
                        helpArr.push(y[i] + " " + x[j]);                        
                    }
                }
                return helpArr;
            }
        }

میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش آپدیت شد
0

کد کامل همراه با مثال ها:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>three Arrays combinations</title>
    <style>

    </style>
</head>
<body>
    <h1> look console!! </h1>

    <script>    
        let base = {"variants": [
                                    {"options": [{"name": "red"},{"name": "blue"},{"name": "green"},{"name": "yellow"}]},
                                    {"options": [{"name": "small"},{"name": "medium"},{"name": "large"}]},
                                    {"options": [{"name": "i"},{"name": "ii"},{"name": "iii"}]}
                                ]};
        let base2 = {"variants": [
                                    {"options": [{"name": "red"},{"name": "blue"},{"name": "green"},{"name": "yellow"}]}
                                ]};
        let base3 = {"variants": [
                                    {"options": [{"name": "red"},{"name": "blue"},{"name": "green"},{"name": "yellow"}]},
                                    {"options": [{"name": "small"},{"name": "medium"},{"name": "large"}]}
                                ]};

        <!-- seprate arrays from object / create array of arrays -->
        function seprateArr(base) {
            let baseArr = [];
            for (let i = 0; i < base['variants'].length; i++) { 
                baseArr[i] = new Array();// array of arrays
            } 

            for(var i = 0; i < base['variants'].length; i++) {
                for(var j = 0; j < base['variants'][i]['options'].length; j++) {
                    baseArr[i].push(base['variants'][i]['options'][j]['name']);
                }
            }
            return baseArr;         
        }
        console.log(seprateArr(base));

        <!-- combination dynamic number arrays -->
        function combinationArr(baseArray) {
            let helpArr = [];

            if (baseArray.length == 1) return baseArray[0];
            else if (baseArray.length == 2) {
                for(var i = 0; i < baseArr[0].length; i++) {
                    for(var j = 0; j < baseArr[1].length; j++) {
                        helpArr.push(baseArr[0][i] + " " + baseArr[1][j]);                      
                    }
                }
                return helpArr;
            } else {
                let x = baseArray.pop();
                let y = combinationArr(baseArray);

                for(var i = 0; i < y.length; i++) {
                    for(var j = 0; j < x.length; j++) {
                        helpArr.push(y[i] + " " + x[j]);                        
                    }
                }
                return helpArr;
            }
        }

        console.log(combinationArr(seprateArr(base)));
        console.log(combinationArr(seprateArr(base2)));
        console.log(combinationArr(seprateArr(base3)));

    </script>
</body>
</html>

</body></html>


میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش مطرح شد
0

لطفا شما هم کدها رو نگاه کنید و اگر ایرادی داشتش بفرمایید.
راه حل شما رو درست متوجه نشدم، اگر راه حل بهتری هم پیدا کردید قرار بدید ممنون میشم.


امین محمدزاده
تخصص : برنامه نویسی وب - Laravel
@amin.webdesign 4 سال پیش آپدیت شد
1

@milad
تست کردم و اوکی بود. ممنون
البته در تک ردیف ، نتیجه تو یه آرایه دیگه قرار میگیره. یعنی آرایه در آرایه میشه که شرط زیر رو اصلاح کردم و درست شد.
کد اولیه :

if (baseArray.length === 1) return baseArray;

اصلاح شده :

if (baseArray.length === 1) return baseArray[0];

امین محمدزاده
تخصص : برنامه نویسی وب - Laravel
@amin.webdesign 4 سال پیش مطرح شد
1

@milad
کد نهایی با یه سری تغییرات که بعدا هم به درد دوستان بخوره:

<script>

        let base = {"variants": [
            {"options": [{"name": "red"},{"name": "blue"},{"name": "green"},{"name": "yellow"}]},
            {"options": [{"name": "small"},{"name": "medium"},{"name": "large"}]},
            {"options": [{"name": "i"},{"name": "ii"},{"name": "iii"}]}
        ]};

        function seprateArr(base) {
            let baseArr = [];
            for (let i = 0; i < base['variants'].length; i++) { 
                baseArr[i] = new Array();// array of arrays
            } 

            for(var i = 0; i < base['variants'].length; i++) {
                for(var j = 0; j < base['variants'][i]['options'].length; j++) {
                    baseArr[i].push(base['variants'][i]['options'][j]['name']);
                }
            }
            return baseArr;         
        }

        <!-- combination dynamic number arrays -->
        function combinationArr(baseArray) {
            let helpArr = [];

            if (baseArray.length === 1) return baseArray[0];
            else if (baseArray.length > 1) {
                let x = baseArray.pop();
                let y = combinationArr(baseArray);

                for(var i = 0; i < y.length; i++) {
                    for(var j = 0; j < x.length; j++) {
                        helpArr.push(y[i] + " " + x[j]);
                    }
                }
                return helpArr;
            }
        }
        //document.getElementById('results').innerHTML = combinationArr(seprateArr(base));
        combinationArr(seprateArr(base)).forEach(function (i,v) {
            console.log(i);
        });
    </script>

میلاد-م
تخصص : توسعه‌دهنده رابط کاربری - Fron...
@milad 4 سال پیش مطرح شد
0

خواهش میکنم، زنده باشید.
ممنون از توجه تون، درست می فرمایید، من هم تصحیحش کردم.


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام