سلام
من یه آرایه ای دارم که میخوام پارامترهای اون با نمونه فرمتی که نوشتم نشون داده بشه.
من این کار رو با 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"]
ممنون میشم از دوستان بتونه کمک کنه
تابع رو بصورت پویا و به روش بازگشتی نوشتم.
مثال ها رو هم امتحان کردم، همگی درست هستند.
<!-- 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;
}
}
از کلاس Map و متد set استفاده کن
()let results = new Map
اونجایی هم که داری push میکنی به جاش ست کن (variant['options'][j]['name'])results.set
البته ست رو فکر کنم بد نوشتم باهاش یکم ور برو دستت میاد
@majidmagic
خیلی ممنون از پاسخت ولی فعلا با یه روش دیگه بردم جلو چون زمان زیادی ندارم. ان شاالله حتما یه وقت دیگه از روشی که فرمودید استفاده کردم بازخورد رو همینجا منتشر میکنم.
ابتدا مسئله رو بصورت ساده حل می کنیم:
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);
و این هم همه ی کدها بصورت یکجا و در کنار هم:
<!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>
@milad
سلام. ممنون از پاسختون ولی مسئله اصلی آبجکت من اینه که داینامیک هست و تعداد سطر و ستون یکسانی نداره که بخوایم براش تعداد for مشخصی بنویسیم. میتونه فقط یک ردیف داشته باشه یا بیشتر از اون که بر اساس تعداد ردیف ها و تعداد ستون های هر ردیف خروجی داینامیک بده ولی کد شما برای حالت استاتیک هست.
خواهش میکنم.
به چه صورت پویا هستش؟
در اینجا سه تا آرایه بودش. / منظورتون اینه که تنها تعداد آرایه های درونی متغیر هستش؟ یعنی یک یا دو یا سه یا 4 تا یا 5 تا و ... باشه؟
یا اینکه منظورتون پویایی بیشتری بصورت درونی هستش؟
لطفا لااقل سه مثال دیگر را هم اینجا بنویسید.
ما توی آبجکتمون یه سری ردیف ها داریم که با 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 کردن آرایه شاید توی جاوااسکریپت با روش دیگه ای عمل میکنه.
تابع رو بصورت پویا و به روش بازگشتی نوشتم.
مثال ها رو هم امتحان کردم، همگی درست هستند.
<!-- 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;
}
}
کد کامل همراه با مثال ها:
<!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>
لطفا شما هم کدها رو نگاه کنید و اگر ایرادی داشتش بفرمایید.
راه حل شما رو درست متوجه نشدم، اگر راه حل بهتری هم پیدا کردید قرار بدید ممنون میشم.
@milad
تست کردم و اوکی بود. ممنون
البته در تک ردیف ، نتیجه تو یه آرایه دیگه قرار میگیره. یعنی آرایه در آرایه میشه که شرط زیر رو اصلاح کردم و درست شد.
کد اولیه :
if (baseArray.length === 1) return baseArray;
اصلاح شده :
if (baseArray.length === 1) return baseArray[0];
@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>
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟