how to get preferred array pushed in javascript - javascript

I am receiving data in object form. that object contains properties in which three keys are holding array values. I want to push concat those three array into one master Array. But should be in preferred sequence. Like
var obj = {'type':['a','b'],'power':[500,700],'make':['2012','2015']}
oneArray(obj,'make','type','power')
The master Array should have first 'make', 'type' and then 'power' keys Array from object. Right now it is coming in order which is given in obj
Fidde
var obj = {'type':['a','b'],'power':[500,700],'make':['2012','2015']}
var oneArray = function (obj,first,second,third){
var newObj = obj;
var list = [];
for(var key in newObj){
if (newObj[key] instanceof Array) {
if (!list) {
list = newObj[key];
}
else {
list = list.concat(newObj[key]);
}
}
}
newObj['all'] = list;
return newObj
}
console.log(oneArray(obj,'make','type','power'))

I'm not sure I have understood your question, but try this...
This onArray() function takes parameters that indicating priorities in orderly manner but first parameter.
var obj = {'type':['a','b'],'power':[500,700],'make':['2012','2015']}
var oneArray = function(obj) {
var newObj = obj;
var list = [];
var priorityList = arguments;
for( var i = 1 ; i < priorityList.length ; i++ ) {
if( newObj[ priorityList[i] ] instanceof Array ) {
for( var key in newObj[ priorityList[i] ] ) {
list.push( newObj[ priorityList[i] ][ key ] );
}
}
}
newObj['all'] = list;
return newObj;
}
console.log(oneArray(obj,'make','type','power'));

Related

reduce key value pairs in JS Array to object

I have one object that I had to take apart into two arrays to handle properly.
It looked like this:
{
city:"stuttgart",
street:"randomstreet",
...
}
Since it needs to fit a certain directive I had to convert it to:
[
{key:"city", value:"stuttgart"}
{key:"street", value:"randomstreet"},
...
]
for this I first used
var mapFromObjectWithIndex = function (array) {
return $.map(array, function(value, index) {
return [value];
});
};
var mapFromObjectWithValue = function (array) {
return $.map(array, function(value, index) {
return [index];
});
});
to create two arrays, one containing the old key, the other one is holding the old value. Then I created another, two dimensional array map them into a single array doing this
var mapToArray = function (arrayValue, arrayIndex) {
var tableData = [];
for (var i = 0; i<arrayIndex.length; i++){
tableData[i] = {key:arrayIndex[i] , value:arrayValue[i]};
}
return tableData;
};
(maybe I have already messed up by here, can this be done any easier?)
Now, I use the array (tableData) to display the data in a form. The value fields can be edited. In the end, I want to convert the array (tableData) to its original. (see first object)
Please note, that the original object doesn't only contain strings as values, but can also contain objects as well.
I think conversion can be definitely easier:
var obj = {
city:"stuttgart",
street:"randomstreet",
};
var tableData = Object.keys(obj).map(k => {return {key: k, value: obj[k]}});
console.log(tableData);
var dataBack = {};
tableData.forEach(o => dataBack[o.key] = o.value);
console.log(dataBack);
What do you want to do with objects? Do you want to expand them as well? If yes you can do something like this (and it works with nested objects as well):
var obj = {
city:"stuttgart",
street:"randomstreet",
obj: {a: 'a', b: 'b'},
subObject: {aha: {z: 'z', y: 'y'}}
};
function trasformToTableData(obj) {
if (typeof obj !== 'object') return obj;
return Object.keys(obj).map(k => {return {key: k, value: trasformToTableData(obj[k])}});
}
var tableData = trasformToTableData(obj);
console.log(tableData);
function transformBack(obj) {
if (Array.isArray(obj)) {
var support ={};
for (let i = 0; i < obj.length; i++) {
support[obj[i].key] = transformBack(obj[i].value)
}
return support;
}
return obj;
}
var dataBack = {};
tableData.forEach(o => dataBack[o.key] = transformBack(o.value));
console.log(dataBack);
Let's have some fun and turn our object into iterable to do the job as follows;
var input = {city:"stuttgart", street:"randomstreet", number: "42"};
output = [];
input[Symbol.iterator] = function*(){
var ok = Object.keys(this),
i = 0;
while (i < ok.length) yield {key : ok[i], value: this[ok[i++]]};
};
output = [...input];
console.log(output);
This function will map your object to an array when you call objVar.mapToArray(), by using Object.keys() and .map()
Object.prototype.mapToArray = function() {
return Object.keys(this).map(function(v) {
return { key: v, value: this[v] };
}.bind(this));
}
I would do something like this:
var dataObj = {
city:"stuttgart",
street:"randomstreet",
};
function toKeyValue(obj) {
var arr = [];
for (var key in obj) {
if(obj.hasOwnProperty(key)) {
arr.push({'key': key, 'value': obj[key]});
}
}
return arr;
}
var arrayKeyValue = toKeyValue(dataObj);
console.log(arrayKeyValue);

How to recursively merge 2 javascript objects?

I have 2 objects that I need to merge and keep all properties in tact, tried with jQuery $.extend but I cant get it to work . I tried all posts with how to merge javascript objects but simply cant get this to work.
var thz_icon_source = {"Spinners":["spinnericon1","spinnericon2"],"Awesome":["awesomeicon1","awesomeicon2"]};
var fa_icon_source = {"Spinners":["faspinner1","faspinner2"],"Awesome":["faawesome1","faawesome2"]};
var new_source ={};
$.extend(new_source,fa_icon_source,thz_icon_source);
console.log(thz_icon_source);
console.log(fa_icon_source);
console.log(new_source);
desired output should be like
{
"Spinners":["faspinner1","faspinner2","spinnericon1","spinnericon2"],
"Awesome":["faawesome1","faawesome2","awesomeicon1","awesomeicon2"]
}
This post Merge two json/javascript arrays in to one array has a simple object mine is not same as that one.
Demo
function mergeJSON(json1,json2)
{
var result = json1 ;
for (var prop in json2)
{
if (json2.hasOwnProperty(prop))
{
result[prop] = result[prop].concat(json2[prop]);
}
}
return result;
}
$.extend merges in missing properties, it doesn't combine the properties that are in common. You need to write a loop.
var thz_icon_source = {
"Spinners": ["spinnericon1", "spinnericon2"],
"Awesome": ["awesomeicon1", "awesomeicon2"]
};
var fa_icon_source = {
"Spinners": ["faspinner1", "faspinner2"],
"Awesome": ["faawesome1", "faawesome2"]
};
var new_source = {};
// First add in the new elements from thz_icon_source
$.extend(new_source, fa_icon_source, thz_icon_source);
// Now merge the common elements
$.each(fa_icon_source, function(k, e) {
if (thz_icon_source.hasOwnProperty(k)) {
new_source[k] = e.concat(thz_icon_source[k]);
}
});
console.log(thz_icon_source);
console.log(fa_icon_source);
console.log(new_source);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can use this prototype to merge 2 or more objects the way you want it:
Object.prototype.assignDeep = function() {
var self = this;
Object.keys(arguments).forEach(obj => {
Object.keys(self).forEach(val => {
if (arguments[obj].hasOwnProperty(val)) {
var tmp = arguments[obj][val] instanceof Array ? arguments[obj][val] : [arguments[obj][val]];
self[val] = self[val].concat(tmp);
}
});
});
return self;
}
var thz_icon_source = {"Spinners":["spinnericon1","spinnericon2"],"Awesome":["awesomeicon1","awesomeicon2"]};
var fa_icon_source = {"Spinners":["faspinner1","faspinner2"],"Awesome":["faawesome1","faawesome2"]};
var b = thz_icon_source.assignDeep(fa_icon_source);
console.log(b);
You should use a loops with .concat():
function objectConcatArrays(){
var a = arguments, o = {};
for(var i=0,l=a.length; i<l; i++){
for(var p in a[i]){
if(p in o){
o[p] = o[p].concat(a[i][p]);
}
else{
o[p] = a[i][p];
}
}
}
return o;
}
var thz_icon_source = {"Spinners":["spinnericon1","spinnericon2"],"Awesome":["awesomeicon1","awesomeicon2"]};
var fa_icon_source = {"Spinners":["faspinner1","faspinner2"],"Awesome":["faawesome1","faawesome2"]};
var res = objectConcatArrays(thz_icon_source, fa_icon_source);
console.log(res);
Each argument represents an Object of Arrays. Add more if you want.

Javascript sorting Object dates

After looping I got following array. Is it possible to sort this from current date to latest.
//Sortering
var arr = {};
var key = "";
var teller = 0;
for (var i = 0; i < schedule_id.length; i++) {
//Ajax call maken
$.ajax({
url: "http://api.viewer.zmags.com/schedules/" + schedule_id[i] + "?key=" + api_key
})
//WdInit after 10 calls
.done(function(data){
//Check publicatieID is not null
if (undefined === data.scheduleEntries[default_pub]|| null === data.scheduleEntries[default_pub]) {
}
else
{
var key = schedule_id[teller];
//loopen doorheen resultaat call
$.each(data.scheduleEntries, function(index, entry){
arr[key] = entry.startDate;
})
}
teller++;
})
}
arr: Object
7aaabbec: "2015-02-09T23:00:00.000Z"
31ba19e7: "2015-02-24T23:01:00.000Z"
31ff78e7: "2015-02-24T23:01:00.000Z"
159a11a7: "2015-02-10T23:01:00.000Z"
1339d0e9: "2015-02-17T23:01:00.000Z"
Code that I already got but error: Undefined is not a function
arr.sort(function(a, b) {
return a - b;
});
Objects have no order. You cannot order an object. You'd have to turn this into an array first, which in turn cannot have arbitrary keys, but is orderable.
In Javascript:
objects: key-value collections with undefined order
arrays: lists with order, but without (meaningful) keys
First get keys from object, you use something like underscore.js for this:
var keyList = _.keys( arr );
// sort keyList
keyList = keyList.sort();
// Now, do anything by getting values for sorted keys
for ( key in keyList ) {
console.log( arr[ key ] );
}
Just read your latest comment... for your case you can do it by first converting into a list of lists or list of key-val pairs
// convert into List of [ key, value ]
val pairList = _.pairs( arr );
// sort using values
pairList = pairList.sort( function( a, b ) {
// use moment.js to get date functions
var aMoment = moment( a[ 1 ] )
var bMoment = moment( b[ 1 ] )
// change based on reverse-sorted or sorted.
return bMement.diff( aMement );
} );
// Now sorted use as you want
for ( keyVal in pairList ) {
console.log( keyVal[ 0 ] + " -> " + keyVal[ 0 ] );
}
Use normal array to store the values so you can order them:
arr = [];
loopen doorheen resultaat call
$.each(data.scheduleEntries, function(index, entry){
arr.push( {'key':key, 'date':entry.startDate} );
})
arr.sort(function(a, b){
return a['date'] > b['date']; //this may need a better comparision...
});
UPDATE:
to extract the hash keys after the sorting just loop the array:
var sorted_keys = [];
for(var i = 0; i < arr.length; i++){
sorted_keys.push( arr[i] );
}
By looping object, get all dates into array and sort them and make the object again
var myObj = {
'7aaabbec': "2015-02-09T23:00:00.000Z",
'31ba19e7': "2015-02-24T23:01:00.000Z",
'31ff78e7': "2015-02-24T23:01:00.000Z",
'159a11a7': "2015-02-10T23:01:00.000Z",
'1339d0e9': "2015-02-17T23:01:00.000Z"
};
var timeArray = [], newObj = {};
for(var key in myObj){
timeArray.push([key,myObj[key]]);
}
timeArray.sort(function(a, b) {return new Date(a[1]) - new Date(b[1])});
//console.log(timeArray);
var j=0,k=1;
for(var i=0;i<timeArray.length;i++){
newObj[timeArray[i][j]] = new Date(timeArray[i][k]);
}
$("#result").html(JSON.stringify(newObj));
Working example is here

merge two json arrays with push on item value

I have the following json array:
array 1:
fruits1 = [{"fruit":"banana","amount":"2","color":"yellow"},{"fruit":"apple","amount":"5","color":"red"},{"fruit":"kiwi","amount":"1","color":"green"}]
array 2:
fruits2 = [{"fruit":"banana","sold":"1","stock":"3"},{"fruit":"apple","sold":"3","stock":"5"},{"fruit":"kiwi","sold":"2","stock":"3"}]
I would like to get just one array which has the results merged according to the fruits value like this:
fruits = [{"fruit":"banana","amount":"2","color":"yellow","sold":"1","stock":"3"},{"fruit":"apple","amount":"5","color":"red","sold":"3","stock":"5"},{"fruit":"kiwi","amount":"1","color":"green","sold":"2","stock":"3"}]
I need to do something like
foreach item.fruit where fruit = fruit from initial array
fruits.push item
Any idea?
Try this logic:
function merge_options(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}
var obj1 = [];
for (var i = 0; i < fruits1.length ; i++) {
obj1[fruits1[i].fruit] = fruits1[i];
}
var obj2 = [];
for (var i = 0; i < fruits2.length ; i++) {
obj2[fruits2[i].fruit] = fruits2[i];
}
var fruits = []
for (var key in obj1) {
fruits.push(merge_options(obj1[key],obj2[key]));
}
console.log(fruits);
You can do something like this with javascript
// create a hash like {fruit_name -> object}
f1 = {};
fruits1.forEach(function(p) {
f1[p.fruit] = p;
});
// merge second array into above hash on fruit_name
fruits2.forEach(function(p) {
for (var a in p) { f1[p.fruit][a] = p[a];}
});
//fruits1 will now contain result;
//if you don't want to spoil fruit1 array, clone p inside 'fruits1.forEach' above before assigning it to 'f1[p.fruit]'. And at the end, create a new array out of f1
Here's a generic way that works with your data:
function joinObjects(initial, other, predicate, valueSelector) {
if(typeof(predicate) !== 'function') throw 'predicate must be a function';
if(typeof(valueSelector) !== 'function') throw 'valueSelector must be a function';
// make a clone of the original object so its not modified
var clone = jQuery.extend(true, {}, initial);
// iterate over the initial and other collections
for(var cloneKey in clone) {
if (!clone.hasOwnProperty(cloneKey)) continue;
for(var otherKey in other) {
if (!other.hasOwnProperty(otherKey)) continue;
// if the predicate is truthy, get the values
if (predicate(clone[cloneKey], other[otherKey])) {
// pull only the values you want to merge
var values = valueSelector(other[otherKey]);
// iterate over the values add them to the cloned initial object
for(var valueKey in values) {
if (values.hasOwnProperty(valueKey)) {
clone[cloneKey][valueKey] = values[valueKey];
}
}
}
}
}
return clone;
}
var fruits1 = [{"fruit":"banana","amount":"2","color":"yellow"},{"fruit":"apple","amount":"5","color":"red"},{"fruit":"kiwi","amount":"1","color":"green"}];
var fruits2 = [{"fruit":"banana","sold":"1","stock":"3"},{"fruit":"apple","sold":"3","stock":"5"},{"fruit":"kiwi","sold":"2","stock":"3"}];
var finalFruits = joinObjects(fruits1, fruits2,
function(left, right) { return left.fruit == right.fruit },
function(other) {
return {
sold: other.sold,
stock: other.stock
};
});
console.log(finalFruits);

Converting js array into dictionary map

I have this array:
["userconfig", "general", "name"]
and I would like it to look like this
data_structure["userconfig"]["general"]["name"]
I have tried this function:
inputID = "userconfig-general-name"
function GetDataByID(inputID){
var position = '';
for (var i = 0; i < inputID.length; i++) {
var hirarchy = inputID[i].split('-');
for (var index = 0; index < hirarchy.length; index++) {
position += '["'+ hirarchy[index] +'"]';
}
}
return data_structure[position];
}
while hirarchy is the array. I get the [position] as a string which is not working well.
how can I make a js function which builds the object path dynamically by an array?
var arr = ["userconfig", "general", "name"];
var dataStructure = arr.reduceRight(function (value, key) {
var obj = {};
obj[key] = value;
return obj;
}, 'myVal');
Ends up as:
{ userconfig : { general : { name : 'myVal' } } }
Note that you may need a polyfill for the reduceRight method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight
The below function will take an object to modify and an array filled with the properties needed:
function objPath(obj,path){
path.forEach(function(item){
obj[item] = {};
obj = obj[item];
});
}
var myobj = {};
objPath(myobj,["test","test2","test3"]);
console.log(myobj);
//outputs
Object {test: Object}
test: Object
test2: Object
test3: Object
The function loops over the array creating the new object property as a new object. It then puts a reference to the new object into obj so that the next property on the new object can be made.
JSFiddle
Recursive function
var array = ["userconfig", "general", "name"];
function toAssociative(array) {
var index = array.shift();
var next = null;
if (array.length > 0) {
next = toAssociative(array);
}
var result = new Array();
result[index] = next;
return result;
}

Categories