I have as a result from an input form a couple of strings and I want them to convert them, so they fit as data for my ajax-request. I am looking for an easy way, but I can't get it right. Basically I want to convert/map this array:
[
{ name: "[1][apples]", value: "2" }
{ name: "[1][melons]", value: "1" }
{ name: "[2][apples]", value: "2" }
{ name: "[2][melons]", value: "4" }
{ name: "[3][apples]", value: "3" }
{ name: "[3][melons]", value: "2" }
]
into
[{"id": 1, "apples": 2, "melons": 1}, {"id": 2, "apples": 2, "melons": 4}, {...}]
Any idea? I would appreciate some hint? I could't not find an easy solution via html though.
Thanks
you can use a for loop to access each element and display them.
Refer to this link. For loop in multidimensional javascript array
Firstly, I have replaced the square brackets using a regular expression and formed a new array. After that, I have merged object having same ID using spread operator.
You can refer to the code below which solves this problem.
let array = [
{ name: "[1][apples]", value: "2" },
{ name: "[1][melons]", value: "1" },
{ name: "[2][apples]", value: "2" },
{ name: "[2][melons]", value: "4" },
{ name: "[3][apples]", value: "3" },
{ name: "[3][melons]", value: "2" }];
let newArray = [];
let result = [];
array.forEach((obj, i) => {
let nameArray = obj.name.replace(/[\[\]']+/g, ' ').trim().split(' ');
let o = {};
o['id'] = parseInt(nameArray[0]);
o[nameArray[1]] = obj.value;
newArray.push(o);
});
for(let i = 0; i< newArray.length; i++) {
for(let j = i+1; j < newArray.length; j++) {
if(newArray[i].id === newArray[j].id) {
let o = {...newArray[i], ...newArray[j]};
result.push(o);`enter code here`
}
}
}
console.log('Final result', result);
Thanks for the input. I think my question needed to be more specific:
(1) Yes, they are always in order.
(2) My names of my input-tags in html appear to be an multidimensional array. This is not the case! I tried something, but it turned out to be for php.
I found the follow workaround:
function apiAdapter() {
var arrayToCopy = $("#formsteps").serializeArray();
var copiedArray = [];
for (let i = 0; i < arrayToCopy.length; i += 2) {
var id = arrayToCopy[i].name.slice(arrayToCopy[i].name.indexOf('[') + 1, arrayToCopy[i].name.indexOf(']'));
copiedArray.push({ "id": id, "apples": arrayToCopy[i].value, "melons": arrayToCopy[i + 1].value })
}
return copiedArray;
}
As I am new to JavaScript I always look for better solutions. So thanks again for your posts.
I have an 'item' object in JavaScript, and the item can have settings like
color, size, etc.
I need to get all possible combinations in an array.
So lets say we have an item that looks like this:
var newItem = {
name: 'new item',
Settings: [
{name: 'color', values: ['green', 'blue', 'red']},
{name: 'size', values: ['15', '18', '22']},
{name: 'gender',values: ['male', 'female']}
]
};
I need to somehow get this:
[
[{SettingName:'color',value:'green'},{SettingName:'size',value:'15'},{SettingName:'gender',value:'male'}],
[{SettingName:'color',value:'blue'},{SettingName:'size',value:'15'},{SettingName:'gender',value:'male'}],
[{SettingName:'color',value:'red'},{SettingName:'size',value:'15'},{SettingName:'gender',value:'male'}],
[{SettingName:'color',value:'green'},{SettingName:'size',value:'18'},{SettingName:'gender',value:'male'}],
[{SettingName:'color',value:'blue'},{SettingName:'size',value:'18'},{SettingName:'gender',value:'male'}],
[{SettingName:'color',value:'red'},{SettingName:'size',value:'18'},{SettingName:'gender',value:'male'}],
[{SettingName:'color',value:'green'},{SettingName:'size',value:'22'},{SettingName:'gender',value:'male'}],
[{SettingName:'color',value:'blue'},{SettingName:'size',value:'22'},{SettingName:'gender',value:'male'}],
[{SettingName:'color',value:'red'},{SettingName:'size',value:'22'},{SettingName:'gender',value:'male'}],
[{SettingName:'color',value:'green'},{SettingName:'size',value:'15'},{SettingName:'gender',value:'female'}],
[{SettingName:'color',value:'blue'},{SettingName:'size',value:'15'},{SettingName:'gender',value:'female'}],
[{SettingName:'color',value:'red'},{SettingName:'size',value:'15'},{SettingName:'gender',value:'female'}],
[{SettingName:'color',value:'green'},{SettingName:'size',value:'18'},{SettingName:'gender',value:'female'}],
[{SettingName:'color',value:'blue'},{SettingName:'size',value:'18'},{SettingName:'gender',value:'female'}],
[{SettingName:'color',value:'red'},{SettingName:'size',value:'18'},{SettingName:'gender',value:'female'}],
[{SettingName:'color',value:'green'},{SettingName:'size',value:'22'},{SettingName:'gender',value:'female'}],
[{SettingName:'color',value:'blue'},{SettingName:'size',value:'22'},{SettingName:'gender',value:'female'}],
[{SettingName:'color',value:'red'},{SettingName:'size',value:'22'},{SettingName:'gender',value:'female'}]
]
This can be a good interview question.
See JS Bin for running example.
getAllPermutations(newItem);
function getAllPermutations(item) {
var permutations = [];
getAllPermutations0(item, permutations, []);
console.log(permutations);
}
function getAllPermutations0(item, permutations, array) {
if (array && array.length === item.Settings.length) {
permutations.push(array.slice()); // The slice clone the array
return;
}
var index = array.length;
var setting = item.Settings[index];
for (var i = 0; i < setting.values.length; i++) {
if (index === 0)
array = [];
var currValue = setting.values[i];
array.push({
SettingName: setting.name,
value: currValue
});
getAllPermutations0(item, permutations, array);
array.pop(); // pop the old one first
}
}
Here is a none recursive solution. It takes an empty or existing settings "matrix" and a values array, and return a new matrix as a combination of existing matrix content cloned for each new value, appended with pairs of new value setting items.
[A] -> [1,2] gives [A][1][A][2]
[A][1][A][2] -> [X,Y] gives [A][1][X][A][2][Y][A][2][X][A][1][Y]
and so on
function processSettings(settings, name, values) {
if (settings.length == 0) {
values.forEach(function(value) {
settings.push( [{ SettingName: name, value: value }] )
})
} else {
var oldSettings = JSON.parse(JSON.stringify(settings)), settings = [], temp, i = 0
for (i; i<values.length; i++) {
temp = JSON.parse(JSON.stringify(oldSettings))
temp.forEach(function(setting) {
setting.push( { SettingName: name, value: values[i] } )
settings.push(setting)
})
}
}
return settings
}
You can now create the desired settings literal this way :
var settings = []
for (var i=0; i<newItem.Settings.length; i++) {
var item = newItem.Settings[i]
settings = processSettings(settings, item.name, item.values)
}
demo -> http://jsfiddle.net/b4ck98mf/
The above produces this :
[
[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"male"}],
[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"male"}],
[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"male"}],
[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"male"}],
[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"male"}],
[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"male"}],
[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"male"}],
[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"male"}],
[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"male"}],
[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"female"}],
[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"female"}],
[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"female"}],
[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"female"}],
[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"female"}],
[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"female"}],
[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"female"}],
[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"female"}],
[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"female"}]
]
You can use Array.prototype.map(), for loop, while loop, Array.prototype.concat(). Iterate gender values; select each of color, size value in succession beginning at index 0 of either; iterating the furthest adjacent array from current gender, increment the index of the closest adjacent array; merge the resulting two gender arrays to form a single array containing all combinations of gender, color, size
var colors = newItem.Settings[0].values;
var sizes = newItem.Settings[1].values;
var gen = newItem.Settings[2].values;
var i = sizes.length;
var res = [].concat.apply([], gen.map(function(value, key) {
var next = -1;
var arr = [];
for (var curr = 0; curr < i; curr++) {
while (next < i - 1) {
arr.push([{
SettingName: "gender",
value: value
}, {
SettingName: "size",
value: sizes[curr]
}, {
SettingName: "color",
value: colors[++next]
}])
}
next = -1;
}
return arr
}))
var newItem = {
"name": "new item",
"Settings": [{
"name": "color",
"values": [
"green",
"blue",
"red"
]
}, {
"name": "size",
"values": [
"15",
"18",
"22"
]
}, {
"name": "gender",
"values": [
"male",
"female"
]
}]
}
var colors = newItem.Settings[0].values;
var sizes = newItem.Settings[1].values;
var gen = newItem.Settings[2].values;
var i = sizes.length;
var res = [].concat.apply([], gen.map(function(value, key) {
var next = -1;
var arr = [];
for (var curr = 0; curr < i; curr++) {
while (next < i - 1) {
arr.push([{
SettingName: "gender",
value: value
}, {
SettingName: "size",
value: sizes[curr]
}, {
SettingName: "color",
value: colors[++next]
}])
}
next = -1;
}
return arr
}))
document.querySelector("pre").textContent = JSON.stringify(res, null, 2)
<pre></pre>
plnkr http://plnkr.co/edit/C2fOJpfwOrlBwHLQ2izh?p=preview
An approach using Array.prototype.reduce(), Array.prototype.sort(), Object.keys(), for loop, while loop
var newItem = {
name: 'new item',
Settings: [
{
name: 'color',
values: ['green', 'blue', 'red']
},
{
name: 'size',
values: ['15', '18', '22']
},
{
name: 'gender',
values: ['male', 'female']
}
]
};
var props = ["SettingName", "value"];
var settings = newItem.Settings;
function p(settings, props) {
var data = settings.reduce(function(res, setting, index) {
var name = setting.name;
var obj = {};
obj[name] = setting.values;
res.push(obj);
return res.length < index ? res : res.sort(function(a, b) {
return a[Object.keys(a)[0]].length - b[Object.keys(b)[0]].length
})
}, []);
var key = data.splice(0, 1)[0];
return [].concat.apply([], key[Object.keys(key)].map(function(value, index) {
return data.reduce(function(v, k) {
var keys = [v, k].map(function(obj) {
return Object.keys(obj)[0]
});
var i = Math.max.apply(Math, [v[keys[0]].length, k[keys[1]].length]);
var next = -1;
var arr = [];
for (var curr = 0; curr < i; curr++) {
while (next < i - 1) {
var a = {};
a[props[0]] = keys[0];
a[props[1]] = v[keys[0]][++next];
var b = {};
b[props[0]] = keys[1];
b[props[1]] = k[keys[1]][next];
var c = {};
c[props[0]] = Object.keys(key)[0];
c[props[1]] = value;
arr.push([a, b, c]);
};
next = -1;
}
return arr
});
}));
}
document.querySelector("pre").textContent = JSON.stringify(
p(settings, props), null, 2
);
<pre></pre>
Split array of objects into new array or objects based on age value in Javascript
var items = [
{name:"Foo", age:16, color:"w"},
{name:"Bar", age:18, color:"b"},
{name:"foo", age:16, color:"w"},
{name:"bar", age:18, color:"w"},
{name:"foobar", age:18, color:"b"},
{name:"barfoo", age:20, color:"w"}
];
How can I return a list like:
var items = [
{age:16,name:"Foo"|"foo",gender:"w"|"w"},
{age:18,name:"Bar"|"bar"|"foobar",gender:"b"|"w"|"b"},
{age:20,name:"barfoo",gender:"w"}
];
I have worked but i got output with 'undefined' in name. Below is my code.
var data = [{age: 21,name: "Walter",color: "black"},{age: 25,name: "sentinel",color: "black"
},{age: 21,name: "Micah",color: "purple"},{age: 25,name: "mike",color: "black"},{age: 21,name: "Danny",color: "white"},{age: 25,name: "mike",color: "black"}];
var obj=data;
var arrayobj = obj.length;
var i, row, arr = obj, ss = {};
for (i = 0; i < arr.length; i++) {
row = arr[i];
ss[row.age] = ss[row.age] || {count: 0};
if (ss[row.age][row.age] === undefined) {
ss[row.age][row.name] = row.name;
ss[row.age]['name']+=row.name+'|';
ss[row.age]['color']+=row.color+'|';
ss[row.age]['count'] += 1;
}
}
console.table(ss);
I'm assuming you want to group the items by their age. Here is one way:
(fiddle)
items.reduce(function(buckets,item){
if(!buckets[item.age]) buckets[item.age] = [];
buckets[item.age].push(item);
return buckets;
},{});
Let's explain:
For each item, if we don't already have a 'bucket' for it, create a new empty one
Add it to the bucket
return the new updated bucket list.
The method returns an object with 3 properties: 16,18 and 20, each containing the objects with that age.
This will work. The output is in different format than one provided by exebook .
Please check and confirm. Here's a fiddle....
** UX Manager
var buckets = [];
for (var item in items) {
var currentAge = items[item].age;
if(!buckets[currentAge]) {
buckets[currentAge] = [];
for (var i in items) {
if (currentAge === items[i].age) {
buckets[currentAge].push(items[i]);
}
}
}
}
var items = [
{name:"Foo", age:16, color:"w"},
{name:"Bar", age:18, color:"b"},
{name:"foo", age:16, color:"w"},
{name:"bar", age:18, color:"w"},
{name:"foobar", age:18, color:"b"},
{name:"barfoo", age:20, color:"w"}
];
var result = [] // THIS IS THE RESULTING ARRAY THAT YOU WANT
function find(age) {
for (var i = 0; i < result.length; i++)
if (result[i].age == age) return i
return -1
}
function append(i, obj) {
result[i].name.push(obj.name)
result[i].color.push(obj.color)
}
for (var i = 0; i < items.length; i++) {
var x = find(items[i].age)
if (x < 0) result.push({ age: items[i].age, name: [items[i].name], color : [items[i].color]})
else append(x, items[i])
}
console.log(result) // PRINT THE RESULT, alternatively you can use alert(result)
The output
[ { age: 16, name: [ 'Foo', 'foo' ], color: [ 'w', 'w' ] },
{ age: 18, name: [ 'Bar', 'bar', 'foobar' ], color: [ 'b', 'w', 'b' ] },
{ age: 20, name: [ 'barfoo' ], color: [ 'w' ] } ]
How can I get the values from this associative array in JavaScript?
I just need the email addresses and not the labels.
(
{
office = ("my#email.com");
home = ("ahome#anotheremail.com");
work = ("nothing#email.com");
},
{
home = ("test#test.se");
}
)
UPDATE: Prefered output in JSON would be:
{
"data": [
{
"email": "my#email.com"
},
{
"email": "ahome#anotheremail.com"
},
{
"email": "nothing#email.com"
},
{
"email": "test#test.se"
}
]
}
Thankful for all input!
What you probably meant to do is:
var x = [{
office: ("my#email.com"),
home: ("ahome#anotheremail.com"),
work: ("nothing#email.com")
},
{
home: ("test#test.se")
}]
and:
for(var j = 0; j < x.length; j++)
{
for(var anItem in x[j])
{
console.log(x[j][anItem])
}
}
// EDIT:
however, it's not the best practice to use for … in.
Maybe you could change your data structure to:
var x = [[{
value: "my#email.com",
type: "office"
},
{
value: "ahome#anotheremail.com",
type: "home"
},
{
value: "nothing#email.com",
type: "work"
}],
[{
value: "test#test.se",
type: "home"
}]];
and iterate over using:
for( var i = 0, xlength = x.length; i < xlength; i++ )
{
for( var j=0, ylength = x[i].length; j < ylength; j++ )
{
console.log(x[i][j].value);
}
}
Here's a one-liner:
console.log(Object.keys(assoc).map(k => assoc[k]));
where assoc is your associative array.
Edit
I have a better answer here.
You can 'foreach' over the object to get it's properties:
for(var j = 0; j < mySet.length; j++)
{
for(var propName in mySet[j])
{
var emailAddress = mySet[j][propName];
// Do Stuff
}
}
Answer for edited question:
var ret = {data: []};
for(var j = 0; j < x.length; j++)
{
for(var anItem in x[j])
{
ret.data.push({
email: x[j][anItem]
});
}
}
console.log(ret);
The result is kept in ret.
Is it your input in JSON format? Because if so, it's the wrong syntax. However
let _in = [
{
office : "my#email.com",
home : "ahome#anotheremail.com",
work : "nothing#email.com",
},
{
home : "test#test.se"
}
]
let _out = []
_in.forEach( record => {
_out = _out.concat(Object.values(record).map(x => new Object({email : x})))
})
console.log(_out)
for each record I extracted values and "packed" into an object with the "email" attrbiute, then I merged all those arrays obtained from the original array of records
It seems that you're looking for Object.values.