JavaScript: Adding to an associative array - javascript

I have a function called insert which takes two parameters (name and telnumber).
When I call this function I want to add to an associative array.
So for example, when I do the following:
insert("John", "999");
insert("Adam", "5433");
I want to it so be stored like this:
[0]
{
name: John, number: 999
}
[1]
{
name: Adam, number: 5433
}

Something like this should do the trick:
var arr = [];
function insert(name, number) {
arr.push({
name: name,
number: number
});
}

I would use something like this;
var contacts = [];
var addContact = function(name, phone) {
contacts.push({ name: name, phone: phone });
};
// Usage
addContact('John', '999');
addContact('Adam', '5433');
I don’t think you should try to parse the phone number as an integer as it could contain white-spaces, plus signs (+) and maybe even start with a zero (0).

var users = [];
users.push({name: "John", number: "999"});
users.push({name: "Adam", number: "5433"});

If you want you can add your function to Array.prototype.
Array.prototype.insert = function( key, val ) {
var obj = {};
obj[ key ] = val;
this.push( obj );
return this;
};
And use it like this.
var my_array = [].insert("John", "999")
.insert("Adam", "5433")
.insert("yowza", "1");
[
0: {"John":"999"},
1: {"Adam":"5433"},
2: {"yowza":"1"}
]

I will assume you're using some array reference with insert:
var arr;
function insert(na, nu) {
nu = Number(nu) || 0;
//alternatively
nu = parseInt(nu, 10);
arr.push({ name: na, number: nu });
}
arr = [];
insert("John", "999");
insert("Adam", "5433");

There is no such term as an "associative array" in JavaScript, though you can use following:
var list = [];
function insert(name, number) {
list.push({
name: name,
number: number
});
}

Related

NodeJS loop through string and get the exact output

In NodeJS I have a string like this
"Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?"
In the string you can see there are multiple Package, Qty and Price. Now I want to send email for each Qty and Package. So if you see Package Two it has Qty 3. So in that case there it will send 3 emails with Package and Price. So basically it will send email for each Qty with corresponding Package and Price.
So for now I have my code like this
var string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
var packArr = string.split('?');
var PackageName;
var PackagePrice;
for (var i = 0; i < packArr.length; i++) {
if( packArr[i].length > 0 ) {
let packageQty = packArr[i].split('&');
for (var j = 0; j < packageQty.length; j++) {
if( packageQty[j].match(/Package=/i) ) {
PackageName = packageQty[j].replace(/Package=/g,'');
console.log(PackageName);
}
if( packageQty[j].match(/Price=/i) ) {
PackagePrice = packageQty[j].replace(/Price=/g,'');
console.log(PackagePrice);
}
if (packageQty[j].match(/Qty=/i)) {
var ret = packageQty[j].replace(/Qty=/g,'');
var Pck = Number(ret);
for (var k = 1; k <= Pck; k++) {
console.log(k);
console.log('Package Name ' + PackageName);
console.log('Package Price ' + PackagePrice);
//send email with Package Name, Package Price
if( k == Pck ) {
break;
}
}
}
}
}
}
The above code actually not working properly. It is not getting the Package and Price properly for each loop. So can someone tell me how to do this in a easy way? Any help and suggestions will be really appreciable.
Here's a much cleaner way using querystring package
const string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
const qs = require('querystring');
// We split the string into multiple valid query strings.
// We strip the empty item due to the '?' at the end using .filter(Boolean)
const items = string.split('?').filter(Boolean);
// We loop through each group
for(const query of items) {
// Parse the query string of each group
const { Package, Qty, Price } = qs.parse(query);
for(let i = 0; i < Number(Qty); i++) {
// We send the email here <Qty> times.
console.log('Package Name ' + Package);
console.log('Package Price ' + Price);
}
}
I don't know how you feel about libraries, but Ramda (disclaimer: I'm one of the authors) is well-suited to data-transformations. And this screams for some straightforward data transformation.
I might use it to write a conversion function that changes your initial data into something like:
[
{Package: "Package", Price: 123, Qty: 1},
{Package: "Package Two", Price: 702, Qty: 3},
{Package: "Package Three", Price: 199, Qty: 1},
{Package: "Package One", Price: 852, Qty: 4}
]
This new format should then be easy to work with.
Here is a implementation that does this:
const {pipe, split, filter, map, fromPairs, evolve} = R;
const str = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
const convertToObjects = pipe(
split('?'),
filter(Boolean),
map(split('&')),
map(map(split('='))),
map(fromPairs),
map(evolve({Price: Number, Qty: Number}))
);
console.log(convertToObjects(str))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
map, split, and filter should be obvious.
fromPairs turns [['a', 1], ['b', 2]] into {a: 1, b: 2}.
evolve takes a specification mapping property names to transformation functions, and transforms an object by applying those functions to the relevant properties, keeping all other properties intact. Here we use it with the JS Number function to convert {Package: 'Foo', Qty: '2', Price: '456'} into {Package: 'Foo', Qty: 2, Price: 456}.
and pipe creates a pipeline of functions in which the output of one function becomes the input to the next. Values supplied to the resulting function are sent to the first one and the result of the last one is returned.
Extending #Marcos-casagrande example here without external dependency using plain javascript
const string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
// We split the string into multiple valid query strings.
// We strip the empty item due to the '?' at the end using .filter(Boolean)
const items = string.split('?').filter(Boolean);
// We loop through each group
items.map(query => {
// Parse the query string of each group
const {
Package,
Qty,
Price
} = query.split('&').reduce((acc, cur) => {
let arr = cur.split('=');
return {
...acc,
[arr[0]]: arr[1]
};
}, {});
for (let i = 0; i < Number(Qty); i++) {
// We send the email here <Qty> times.
console.log('Package Name ' + Package);
console.log('Package Price ' + Price);
}
})
Another way using only regexes and a few array methods, not requiring nested loops
var input = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?"
var results = input
.split('?')
.map(s => /^Package=(.*?)&Qty=(.*?)&Price=(.*?)$/.exec(s))
.filter(s => s)
.map(s => ({
package: s[1],
qty: parseFloat(s[2]),
price: parseFloat(s[3])
}))
console.log(JSON.stringify(results, null, 4))
Here is a pure JS alternative, please take a look.
function extract(name, string) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(string);
return results == null ? null : results[1];
}
function parse(string) {
items = string.split('?');
results = [];
for (var i in items) {
if (items[i].length == 0) continue;
var item = '?' + items[i];
results.push({
package: extract("Package", item),
qty: extract("Qty", item),
price: extract("Price", item)
})
}
return results;
}
str = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
document.getElementById('output').innerText = JSON.stringify(parse(str));
<div id='output'></div>

javascript loop on object with just one array

i've this structure of object which I need to loop on and find some value on the array ,e.g. find if user name is eq to user2 , I was able to do it with two object ( create another object and put there the array key like users, address etc ) but I want to know If I can do it with only on object,
This is sample of the object
var stuff = {
users :['user1','user2'],
address:['addr1', 'addr2'],
emails:['email1', 'email2'],
};
var stuff = {
users :['user1','user2'],
address:['addr1', 'addr2'],
emails:['email1', 'email2'],
}
console.log(Object.keys(stuff))
output will be
["users", "address", "emails"]
Iterate though content
assuming that you want find user2 in all keys of object.
keys = Object.keys(stuff)
for(let i in keys){
// do something
//console.log(stuff[keys[i]])
ind = stuff[keys[i]].indexOf('user2')
if(ind >=0){
console.log('user2 found in ', keys[i])
}
}
var stuff = {
users :['user1','user2'],
address:['addr1', 'addr2'],
emails:['email1', 'email2'],
};
function check(a) {
for(var key in stuff) {
var arr = stuff[key];
for(var i = 0; i < arr.length; i++) {
return arr[i] == a;
}
}
}
alert(check("user2"));
Check if the Array#indexOf of user2 in stuff.users is not -1:
var stuff = {
users: ['user1', 'user2'],
address: ['addr1', 'addr2'],
emails: ['email1', 'email2'],
};
var isUser2Included = stuff.users.indexOf('user2') !== -1;
console.log(isUser2Included);
Or so:
var stuff = {
users: ['user1', 'user2'],
address: ['addr1', 'addr2'],
emails: ['email1', 'email2'],
};
stuff.findIt = (key, val) => stuff[key].indexOf(val) != -1;
console.log(stuff.findIt('users', 'user1'));
console.log(stuff.findIt('users', 'user3'));
console.log(stuff.findIt('emails', 'email1'));

array indexOf with objects?

I know we can match array values with indexOf in JavaScript. If it matches it wont return -1.
var test = [
1, 2, 3
]
// Returns 2
test.indexOf(3);
Is there a way to match objects? For example?
var test = [
{
name: 'Josh'
}
]
// Would ideally return 0, but of course it's -1.
test.indexOf({ name: 'Josh' });
Since the two objects are distinct (though perhaps equivalent), you can't use indexOf.
You can use findIndex with a callback, and handle the matching based on the properties you want. For instance, to match on all enumerable props:
var target = {name: 'Josh'};
var targetKeys = Object.keys(target);
var index = test.findIndex(function(entry) {
var keys = Object.keys(entry);
return keys.length == targetKeys.length && keys.every(function(key) {
return target.hasOwnProperty(key) && entry[key] === target[key];
});
});
Example:
var test = [
{
name: 'Josh'
}
];
var target = {name: 'Josh'};
var targetKeys = Object.keys(target);
var index = test.findIndex(function(entry) {
var keys = Object.keys(entry);
return keys.length == targetKeys.length && keys.every(function(key) {
return target.hasOwnProperty(key) && entry[key] === target[key];
});
});
console.log(index);
Note that findIndex was added in ES2015, but is fully polyfillable.
Nope, you can't and the explanation is simple. Despite you use the same object literal, two different objects are created. So test would have another reference for the mentioned object if you compare it with the reference you are looking for in indexOf.
This is kind of custom indexOf function. The code just iterates through the items in the object's array and finds the name property of each and then tests for the name you're looking for. Testing for 'Josh' returns 0 and testing for 'Kate' returns 1. Testing for 'Jim' returns -1.
var test = [
{
name: 'Josh'
},
{
name: 'Kate'
}
]
myIndexOf('Kate')
function myIndexOf(name) {
testName = name;
for (var i = 0; i < test.length; i++) {
if(test[i].hasOwnProperty('name')) {
if(test[i].name === testName) {
console.log('name: ' + test[i].name + ' index: ' + i);
return i;
}
}
}
return -1;
}
You can loop on array and then look for what you want
var test = [{ name: 'Josh' }]
const Myname = test.map((item) => { return item.name; }).indexOf("Josh")

how to make array of object using an array?

I have one array
var ar=['aa','cc','po']
I want to push objects in new array after checking the value of given array .In other words
I have these given conditions
var ar=['aa','cc','po']
var arr =[{name:"po"},{name:'aa'},{name:'cc'}];
Expected Output in new Array
[{name:'aa'},{name:'cc'},{name:"po"}]
As "aa" in in 0 index then I added object whose name property aa.
I try like this .but I used two for look .is there any simple way to do this
FIDDLE
var newArr=[];
for(var i=0;i<ar.length ;i++){
var text =ar[i];
for(var j=0;j<arr.length ;j++){
var obj =arr[j];
console.log(obj.name);
/*if(obj.name===text){
newArr.push(obj);
}*/
}
}
console.log(newArr);
This is a proposal in two part, first build an object with the reference to the items of arr and the create a new array with the given items of ar.
var ar = ['aa', 'cc', 'po'],
arr = [{ name: "po" }, { name: 'aa' }, { name: 'cc' }],
object = Object.create(null),
result = [];
arr.forEach(function (a) {
object[a.name] = a;
});
ar.forEach(function (a) {
object[a] && result.push(object[a]);
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
Using forEach iterator and generate object reference based on name and then generate result array using map()
var ar = ['aa', 'cc', 'po']
var arr = [{
name: "po"
}, {
name: 'aa'
}, {
name: 'cc'
}];
var ref = {};
// generating object reference with name property
arr.forEach(function(v) {
ref[v.name] = v;
});
// generating result array
// or you can use forEach as #NinaScholz answer
var res = ar.map(function(v) {
return ref[v];
}).filter(function(v) { // use filter to avoid null values , in case of missing elements
return v != null;
});
document.write('<pre>' + JSON.stringify(res, null, 3) + '</pre>');
Try this:
function convert(source) {
var
obj = [],
i;
for (i = 0; i < source.length; ++i) {
obj.push({name: source[i]});
}
return obj;
}
convert(['aa', 'bb', 'cc']); // [{name:'aa'},{name:'bb'},{name:'cc'}]
This would work if you want to assign values from array in sequence:
var ar=['aa','cc','po']
var arr =[{name:"po"},{name:'aa'},{name:'cc'}];
arr.map(function(obj,key){
obj.name = ar[key];
});
console.log(arr);
Do like this
var ar = ['aa', 'cc', 'po']
var arr = [{ name: "po"}, { name: 'aa'}, { name: 'cc'}];
$.each(ar, function(i, v) {
arr[i].name = v;
});
console.log(arr)
Fiddle
var array=['a','b','c'];
var arrayObj=[];
for(var i=0;i<array.length;i++){
var obj={};
obj.name=array[i];
arrayObj.push(obj);
}
console.log(JSON.stringify(arrayObj));
Output:
[{"name":"a"},{"name":"b"},{"name":"c"}]
I guess this is one very functional way of doing this job with no more than an assignment line. However Anoop Joshi's answer is more elegant provided that the ar array is shorter than equal to in length to the arr array.
var arr = ['aa','cc','po'],
ar = [{name:"po"},{name:'aa'},{name:'cc'}],
res = arr.map(e => ar[ar.findIndex(f => f.name == e)]);
document.write("<pre>" + JSON.stringify(res) + "</pre>");

how to split function in javascript

i have data in
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
i want the result as
Name: John
Employee Id: 2
Salary: $8000
Address: London
is it possible with split() function in javascript?
You can do it with String.split() but in this case it's simpler to use String.replace():
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
description = description.replace(/;/g, '\n').replace(/:/g, ': ');
/*
"Name: John
EmployeeID: 2
Salary: $8000
Address: London"
*/
If you want the result as an object, try:
var f = function (str) {
var x = {}, key2label = { EmployeeID: 'Employee Id' };
str.replace(/(.+?):(.+?)(;|$)/g, function (match, key, value) {
key = key2label[key] || key;
x[key] = value;
});
return x;
};
If a simple string is needed, but you still need to replace keys:
var f2 = function (str) {
var key2label = { EmployeeID: 'Employee Id' };
return str.replace(/(.+?):(.+?)(;|$)/g, function (match, key, value, semi) {
key = key2label[key] || key;
return key + ': ' + value + (semi ? '\n' : '');
});
};
If you really didn't mean to replace keys, this will do it:
var f3 = function (str) {
return str.split(':').join(': ').split(';').join('\n');
};
... or use Matt Ball's answer.
With this statement:
var arrDescription = description.split(";");
you will get an array with all the values. For more info on split check the following link.
you can even join them afterwards :
printf(arrDescription.join(" "));
For more info on join check the following link.
Max
You can probable try like this to display.
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
var arr=new Array();
arr=description.split(";");
for(var i=0;i<arr.length;i++)
document.writeln("<h4>"+arr[i]+"</h4>");
Yes.
You first should split on the semicolon ;. Loop through those results, and split each result on each colon :.
You will have to build the result by hand.
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London"; var splitted = description.split(";");
for(var i = 0; i < splitted.length; i++) { document.write(splitted[i] + ""); }

Categories