Generate multi dimensional array with key value in javascript - javascript

I have an array from json like this:
{"1001":"Account1","1002":"Account2","1003":"Account3"}
and i need convert it to key value format:
[{id:"1001",name:"Account1"},
{id:"1002",name:"Account2"},
{id:"1003",name:"Account3"}]
To do this i wrote this function:
function arrayToMultiArray(list) {
var matrix = [], i;
i = -1;
for (var key in list) {
i++;
matrix[i] = [];
matrix[i].push({"id":key, "name":list[key]});
}
return matrix;
}
but the generated array has brackets for each array
[[{id:"1001",name:"Account1"}],
[{id:"1002",name:"Account2"}],
[{id:"1003",name:"Account3"}]]
How can i remove brackets of internal arrays?

You added array in array.
Just change
i++;
matrix[i] = [];
matrix[i].push({"id":key, "name":list[key]});
to
matrix.push({"id":key, "name":list[key]});

you are creating a multidimensional array.
remove this
i++;
matrix[i] = [];
and do this directly
matrix.push({"id":key, "name":list[key]});

You could do the same with Object.keys and Array.prototype.map
var obj = {"1001":"Account1","1002":"Account2","1003":"Account3"};
var arr = Object.keys(obj).map(function(key) {
return { id : key, name : obj[key] }
});
console.log(arr);

Related

How to concatenate values of duplicate keys

When reading a csv into a javascript dictionary, how can I concatenate values of what would otherwise be duplicate keys? I've seen answers for how to do this with bash, c#, and perl, but I haven't been able to find answers for Javascript. Here's what I have:
var subjects = {};
d3.csv("test.csv", function(data) {
for (var i = 0; i < data.length; i++)
{
subjects[data[i].Id] = data[i].VALUE;
}
console.log(subjects);
});
This, obviously writes over existing keys. Instead, I want the key to be an array of the values. The csv basically looks like:
Id, VALUE
id1, subject1
id2, subject1
id1, subject3
And I want to output as:
{"id1": ["subject1", "subject3"], "id2": ["subject1"]...}
Just check if your output already has the key, if so you add the new value to the array. Else you create an array.
d3.csv("test.csv", function(data) {
var subjects = {};
for (var i = 0; i < data.length; i++)
{
// Check if key already exists
if(subjects.hasOwnProperty(data[i].Id)){
// push data to array
subjects[data[i].Id].push(data[i].VALUE);
}else{
// create new key and array
subjects[data[i].Id] = [data[i].VALUE];
}
}
console.log(subjects);
});
You could make it into an array and then push the content into that array
var subjects = {};
d3.csv("test.csv", function(data) {
for (var i = 0; i < data.length; i++)
{
//first time we see this id, turn it into an array
if(typeof subjects[data[i].Id] != "object"){
subjects[data[i].Id] = [];
}
//push content to the array
subjects[data[i].Id].push(data[i].VALUE);
}
console.log(subjects);
});
Try this inside the for loop:
typeof subjects[data[i].Id] == 'undefined' && (subjects[data[i].Id] = []);
subjects[data[i].Id].push(data[i].VALUE);
You can reduce the footprint of your code slightly if you use reduce:
var out = data.reduce((p, c) => {
const id = c.Id;
p[id] = p[id] || [];
p[id].push(c.VALUE);
return p;
}, {});
RESULT
{
"id1": [
"subject1",
"subject3"
],
"id2": [
"subject1"
]
}
DEMO

How to create key value pair using two arrays in JavaScript?

I have two arrays, keys and commonkeys.
I want to create a key-value pair using these two arrays and the output should be like langKeys.
How to do that?
This is array one:
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT']
This is array two:
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*']
This is the output I need:
var langKeys = {
'en-*': 'en_US',
'es-*': 'es_ES',
'pt-*': 'pt_PT',
'fr-*': 'fr_FR',
'de-*': 'de_DE',
'ja-*': 'ja_JP',
'it-*': 'it_IT',
'*': 'en_US'
};
You can use map() function on one array and create your objects
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT'];
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*'];
var output = keys.map(function(obj,index){
var myobj = {};
myobj[commonKeys[index]] = obj;
return myobj;
});
console.log(output);
JavaScript is a very versatile language, so it is possible to do what you want in a number of ways. You could use a basic loop to iterate through the arrays, like this:
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT']
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*']
var i;
var currentKey;
var currentVal;
var result = {}
for (i = 0; i < keys.length; i++) {
currentKey = commonKeys[i];
currentVal = keys[i];
result[currentKey] = currentVal;
}
This example will work in all browsers.
ES6 update:
let commonKeys = ['en-*', 'es-*', 'pt-*', 'fr-*', 'de-*', 'ja-*', 'it-*', '*'];
let keys = ['en_US', 'es_ES', 'pt_PT', 'fr_FR', 'de_DE', 'ja_JP', 'it_IT', 'en_US'];
let zipArrays = (keysArray, valuesArray) => Object.fromEntries(keysArray.map((value, index) => [value, valuesArray[index]]));
let langKeys = zipArrays(commonKeys, keys);
console.log(langKeys);
// let langKeys = Object.fromEntries(commonKeys.map((val, ind) => [val, keys[ind]]));
What you want to achieve is to create an object from two arrays. The first array contains the values and the second array contains the properties names of the object.
As in javascript you can create new properties with variales, e.g.
objectName[expression] = value; // x = "age"; person[x] = 18,
you can simply do this:
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT'];
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*'];
var langKeys = {};
var i;
for (i=0; i < keys.length; i++) {
langKeys[commonKeys[i]] = keys[i];
}
EDIT
This will work only if both arrays have the same size (actually if keys is smaller or same size than commonKeys).
For the last element of langKeys in your example, you will have to add it manually after the loop.
What you wanted to achieve was maybe something more complicated, but then there is missing information in your question.
Try this may be it helps.
var langKeys = {};
var keys=['en_US','es_ES', 'pt_PT','fr_FR','de_DE','ja_JP','it_IT']
var commonKeys=['en-*','es-*', 'pt-*','fr-*','de-*','ja-*','it-*', '*']
function createArray(element, index, array) {
langKeys[element]= keys[index];
if(!keys[index]){
langKeys[element]= keys[index-(commonKeys.length-1)];
}
}
commonKeys.forEach(createArray);
console.info(langKeys);
Use a for loop to iterate through both of the arrays, and assign one to the other using array[i] where i is a variable representing the index position of the value.
var keys = ['en_US', 'es_ES', 'pt_PT', 'fr_FR', 'de_DE', 'ja_JP', 'it_IT'];
var commonKeys = ['en-*', 'es-*', 'pt-*', 'fr-*', 'de-*', 'ja-*', 'it-*', '*'];
var langKeys = {};
for (var i = 0; i < keys.length; i++) {
var commonkey = commonKeys[i];
langKeys[commonkey] = keys[i];
}
console.log(JSON.stringify(langKeys));
let keys = ['en_US', 'es_ES', 'pt_PT', 'fr_FR', 'de_DE', 'ja_JP', 'it_IT'];
let commonKeys = ['en-*', 'es-*', 'pt-*', 'fr-*', 'de-*', 'ja-*', 'it-*', '*'];
// declaration of empty object where we'll store the key:value
let result = {};
// iteration over first array to pick up the index number
for (let i in keys) {
// for educational purposes, showing the number stored in i (index)
console.log(`index number: ${i}`);
// filling the object with every element indicated by the index
// objects works in the basis of key:value so first position of the index(i)
// will be filled with the first position of the first array (keys) and the second array (commonKeys) and so on.
result[keys[i]] = commonKeys[i];
// keep in mind that for in will iterate through the whole array length
}
console.log(result);

Remove data from an array comparing it to an other array

I am trying to compare the items in "item" array and the copyofOpList array to retrieve the data occurrences in copyofOpList
this is my try:
var _deleteUsedElement1 = function(item) {
for (var i = 0; i < item.length-1; i++){
for (var j = 0; j< $scope.copyofOpList.length-1; j++){
if (item[i].operationCode == $scope.copyofOpList[j].code) {
$scope.copyofOpList.splice(j, 1);
} } } };
$scope.compareArrays = function() {
...Get data from web Service
_deleteUsedElement1(item);
}
the copyofOpList array has 14 elements,and the item array has 2 array
but my code deletes only one occurrence (the first),so please how can I correct my code,to retrieve any occurances in the copyofOpList array comparing to the item array
thanks for help
I'd try to avoid looping inside a loop - that's neither a very elegant nor a very efficient way to get the result you want.
Here's something more elegant and most likely more efficient:
var item = [1,2], copyofOpList = [1,2,3,4,5,6,7];
var _deleteUsedElement1 = function(item, copyofOpList) {
return copyofOpList.filter(function(listItem) {
return item.indexOf(listItem) === -1;
});
};
copyofOpList = _deleteUsedElement1(item, copyofOpList);
console.log(copyofOpList);
//prints [3,4,5,6,7]
}
And since I just noticed that you're comparing object properties, here's a version that filters on matching object properties:
var item = [{opCode:1},{opCode:2}],
copyofOpList = [{opCode:1},{opCode:2},{opCode:3},{opCode:4},{opCode:5},{opCode:6},{opCode:7}];
var _deleteUsedElement1 = function(item, copyofOpList) {
var iOpCodes = item.map(function (i) {return i.opCode;});
return copyofOpList.filter(function(listItem) {
return iOpCodes.indexOf(listItem.opCode) === -1;
});
};
copyofOpList = _deleteUsedElement1(item, copyofOpList);
console.log(copyofOpList);
//prints [{opCode:3},{opCode:4},{opCode:5},{opCode:6},{opCode:7}]
Another benefit of doing it in this manner is that you avoid modifying your arrays while you're still operating on them, a positive effect that both JonSG and Furhan S. mentioned in their answers.
Splicing will change your array. Use a temporary buffer array for new values like this:
var _deleteUsedElement1 = function(item) {
var _temp = [];
for (var i = 0; i < $scope.copyofOpList.length-1; i++){
for (var j = 0; j< item.length-1; j++){
if ($scope.copyofOpList[i].code != item[j].operationCode) {
_temp.push($scope.copyofOpList[j]);
}
}
}
$scope.copyofOpList = _temp;
};

why Object.keys(data).sort() not work as expected?

I am trying to sort my object keys.
But when I'm printing my object, it always print bb first. Can anyone explain this?
It should print aa first ? I already sorted my keys.
My first key should be aa and then second should be bb.
Here is my code
var data = {
bb:"bb",
aa:"cc"
};
Object
.keys(data)
.sort();
console.log(data)
DEMO
Two things:
objects in JS have no order of elements, like arrays do
Object.keys returns an array of object keys, it does not modify the object itself, see the following example:
var data={bb:"bb",aa:"cc"};
var arr = Object.keys(data);
arr.sort();
console.log(arr); // the array IS modified,
// but it has nothing to do with the original object
try this
var data={bb:"bb",aa:"cc"};
var keys = Object.keys(data);
keys.sort();
var obj = {};
for(i = 0; i < keys.length; i++){
obj[keys[i]] = data[keys[i]];
}
console.log(obj);
There is not any method for sorting object keys in JavaScript but you can do this by a object prototype like this.
Object.prototype.sortKeys = function () {
var sorted = {},
key, a = [];
for (key in this) {
if (this.hasOwnProperty(key)) {
a.push(key);
}
}
a.sort();
for (key = 0; key < a.length; key++) {
sorted[a[key]] = this[a[key]];
}
return sorted;
}
var data = {bb: "bb", aa :"cc"};
alert(JSON.stringify(data.sortKeys())); // Returns sorted object data by their keys

Delete JSON items based on array of allowed items

I have an array of allowedFields based on the names of the keys from a JSON array generated from a form.
A number of the retrieved fields are not required at this stage and therefore should not go through the validation process, therefore I want to match the values of the JSON array with the values of the allowedFields array
Returned JSON from form
{"reference":"sdfsdfsdfsd",
"start_date":"04/22/2014",
"end_date":"05//2014",
"status":"1","frequency":"M",
"day":"sat",
"contract_type":"S",
"notice_period":"1M"}
allowedFields = array(
reference,
start_date,
end_date,
contract_type
)
Basically I need to strip out any fields that are not listed in the allowedFields javascript array
1) Parse the JSON to an object.
var obj = JSON.parse(json);
2) Ensure that you've defined your array correctly.
var allowedFields = ['reference','start_date','end_date','contract_type'];
3) Loop over the object and if the key is not in the array delete it.
for (var k in obj) {
if (allowedFields.indexOf(k) < 0) delete obj[k];
}
4) Stringify your object back to JSON.
var str = JSON.stringify(obj);
Output
{"reference":"sdfsdfsdfsd","start_date":"04/22/2014","end_date":"05//2014","contract_type":"S"}
Fiddle
var all = {"reference":"sdfsdfsdfsd",
"status":"1"};
var allowedFields = ['reference']; // note quote marks to create strings
function filter(data, allowed) {
var filtered = {};
for(var id=0; id < allowed.length; ++id) {
var allowedField = allowed[id];
if(data.hasOwnProperty(allowedField)) {
filtered[allowedField] = data[allowedField];
}
}
return filtered;
}
console.log(filter(all, allowedFields));
>> [object Object] {
>> reference: "sdfsdfsdfsd"
>> }
Demo
underscore.js solution:
_.pick(obj,allowedFields)
http://underscorejs.org/#pick
demo
There is also _.omit(obj,string|string[]) that does the opposite.
underscore.js is extremely useful and I use it quite a bit, but you can also pick just the tools you need and include those in your code. The library is quite optimized and there is no need to write your own.
Here is the implementation (from here)
_.pick = function(obj, iterator, context) {
var result = {};
if (_.isFunction(iterator)) {
for (var key in obj) {
var value = obj[key];
if (iterator.call(context, value, key, obj)) result[key] = value;
}
} else {
var keys = concat.apply([], slice.call(arguments, 1));
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i];
if (key in obj) result[key] = obj[key];
}
}
return result;
};

Categories

Resources