Using the following code:
$credits.getCredits = function() {
return $(this).find( 'tbody' ).children( 'tr' ).map(function(){
var $name = $(this).children(':first').html();
var $role = $(this).children(':nth-child(2)').html();
return { $role: $name };
}).get();
}
Which looks through the elements of a credits list and should return a listing like the following:
[
{ 'Make-up': 'Bob' },
{ 'Make-up': 'Susan' },
{ 'Photography': 'Charlie' },
{ 'Lighting': 'Mike' },
{ 'Props': 'One-handed Tony' }
]
It ends up outputting this instead:
[
{ '$role': 'Bob' },
{ '$role': 'Susan' },
{ '$role': 'Charlie' },
{ '$role': 'Mike' },
{ '$role': 'One-handed Tony' }
]
How do you remedy the associative array creation to get the desired output?
Create the object (associative array) in two steps:
var obj = {};
obj[$role] = $name;
return obj
Whenever you use literals to create an object ({foo: bar}), the key will also be taken literally and will not be evaluated.
You need to return it a little differently if you want a dynamic name, like this:
$credits.getCredits = function() {
return $(this).find( 'tbody' ).children( 'tr' ).map(function(){
var $name = $(this).children(':first').html(),
$role = $(this).children(':nth-child(2)').html(),
result = {};
result[$role] = $name;
return result;
}).get();
}
You can try an example here (check the console). This is, well, just the way object literal syntax works. Since these are equivalent:
object.propertyName
object["propertyName"]
You can assign via that same route.
There are no associative arrays in JS. Just create a new object and assign like you want, e.g:
var $obj = {};
$obj.MakeUp = 'Bob';
Related
Javascript:
$(document).ready(function() {
const ores = "../js/json/oreList.json";
const priceURL = "https://esi.tech.ccp.is/latest/markets/prices/?datasource=tranquility";
let oreArray = [];
let priceArray = [];
let total = 0;
// Retrieve list of ores
function getOres() {
$.getJSON(ores, function(ores) {
ores.forEach(function(ore) {
total++;
if (total === 48) {
getPrices();
}
oreArray.push(ore);
});
});
}
// Retrieve all items & prices via API
function getPrices() {
$.getJSON(priceURL, function(prices) {
prices.forEach(function(data) {
priceArray.push(data);
console.log(data);
});
});
}
getOres();
});
The first function creates an internal array from my .JSON file and the second function creates an internal array from the URL.
In the first array oreArray, an object looks like this:
{ id: 1234, name: "Title" }
In the second array priceArray, an object looks like this:
{ type_id: 1234, average_price: 56.34 }
My oreArray has 48 objects and unfortunately the priceArray has about 11,000 objects. I need to create a new array by comparing the two arrays and building new objects, where the ID's match. So for example objects in newArray would look like:
{ id: 1234, name: "Title", average_price: 56.34 }
Basically I'm having trouble figuring out the logic for:
For each object in oreArray, find the object with the same ID value in priceArray and append the new array with a new object using values from both arrays.
I would do it this way:
const ores = "../js/json/oreList.json",
priceURL = "https://esi.tech.ccp.is/latest/markets/prices/?datasource=tranquility";
let oreArray,
priceArray,
joinedArray = [];
function getOres() {
$.getJSON(ores, function(ores) {
oreArray = ores;
getPrices();
});
}
function getPrices() {
$.getJSON(priceURL, function(prices) {
priceArray = prices;
joinPrices();
});
}
function joinPrices() {
oreArray.forEach(function(ore) {
var matchingPrice = getMatchingPrice(ore);
if(matchingPrice !== false) {
joinedArray.push({
id: ore.id,
name: ore.name,
average_price: matchingPrice.average_price
});
}
});
}
function getMatchingPrice(ore) {
for(var i=0; i<priceArray.length; i++) {
if(priceArray[i].type_id === ore.id) {
return priceArray[i];
}
}
return false;
}
getOres();
I think that a good way to approach this problem is by changing the data structure of the average prices a little bit.
Instead of having them in an array, where each item has type_id and average_price field, you might want to consider using an object to store them, where the key is the type_id and the value is the average_price.
To be more concrete, you can replace:
prices.forEach(function(data) {
priceArray.push(data);
});
With:
const pricesMap = {};
prices.forEach(price => {
pricesMap[price.type_id] = price.average_price
});
And when looping on the oreArray, you can access each product's average_price by simply referring to pricesMap[ore.id]
You can check out this JSBin: http://jsbin.com/fogayaqexe/edit?js,console
You can use reduce to loop over each oreArr item and collect the data you need in the accumulator:
var oreArr=[
{ id: 1234, name: "Title" },
{ id: 2234, name: "2Title" },
]
var priceArr= [
{ type_id: 1234, average_price: 56.34 },
{ type_id: 2234, average_price: 256.34 },
{ type_id: 3234, average_price: 56.34 },
{ type_id: 4234, average_price: 56.34 },
]
var resArr = oreArr.reduce((ac,x) => {
var priceMatch = priceArr.find( z => z.type_id === x.id )
if(! priceMatch)
return ac //bail out if no priceMatch found
var res = Object.assign({}, x, priceMatch)
ac.push(res)
return ac
},[])
console.log(resArr)
other methods used:
arrayFind to check intersection
Object.assign to create the merged object to populate the accumulator
I suggest you to change your small json as object
eg : '{"1234":{"id": 1234, "name": "Title" }}';
var json = '{"1234":{"id": 1234, "name": "Title" }}';
oreArray = JSON.parse(json);
alert(oreArray['1234'].name); // oreArray[priceArraySingle.id].name
we can easily match priceArray id with oreArray.
Let's say I have an array of emails:
['a#gmail.com', 'b#gmail.com', 'c#gmail.com']
I need to convert it into an array of objects that looks like this:
[
{
id: 'a#gmail.com',
invite_type: 'EMAIL'
},
{
id: 'b#gmail.com',
invite_type: 'EMAIL'
},
{
id: 'c#gmail.com',
invite_type: 'EMAIL'
}
]
In order to do that, I have written the following code:
$scope.invites = [];
$.each($scope.members, function (index, value) {
let inviteMember = {
'id': value,
invite_type: 'EMAIL'
}
$scope.invites.push(inviteMember);
});
Is there any better way of doing this?
Since you're already using jQuery, you can use jQuery.map() like this:
var originalArray = ['a#gmail.com', 'b#gmail.com', 'c#gmail.com']
var newArray = jQuery.map(originalArray, function(email) {
return {
id: email,
invite_type:'EMAIL'
};
});
jQuery.map() translates all items in a given array into a new array of items. The function I am passing to jQuery.map() is called for every element of the original array and returns a new element that is written to the final array.
There is also the native Array.prototype.map() which is not supported in IE8. If you're not targeting IE8 or if you use a polyfill, then you can use the native .map():
var newArray = originalArray.map(function(email) {
return {
id: email,
invite_type:'EMAIL'
};
});
This pattern
targetArray = []
sourceArray.forEach(function(item) {
let x = do something with item
targetArray.push(x)
})
can be expressed more concisely with map:
targetArray = sourceArray.map(function(item) {
let x = do something with item
return x
})
in your case:
$scope.invites = $scope.members.map(function(value) {
return {
id: value,
invite_type: 'EMAIL'
}
});
I have a program and want to change the object key names in a JSON file with a function. I have already created a function that changes the keys when it is displayed via Angular, but I want to create a function that allows me to change the object key names directly in the JSON file.
Here is a sample of my JSON file ( the actual array contains over 300 entries ):
[
{
"FIELD1":"key",
"FIELD2":"company",
"FIELD3":"team",
"FIELD4":"num_female_eng",
"FIELD5":"num_eng",
"FIELD6":"percent_female_eng",
"FIELD7":"last_updated",
"FIELD8":"Submit more data!",
"FIELD9":"https://github.com/triketora/women-in-software-eng"
},
{
"FIELD1":"all",
"FIELD2":"ALL",
"FIELD3":"N/A",
"FIELD4":"2798",
"FIELD5":"14810",
"FIELD6":"18.89",
"FIELD7":"11/18/2015",
"FIELD8":"",
"FIELD9":""
},
{
"FIELD1":"wellsfargo",
"FIELD2":"Wells Fargo",
"FIELD3":"N/A",
"FIELD4":"1296",
"FIELD5":"5407",
"FIELD6":"23.97",
"FIELD7":"7/22/2015",
"FIELD8":"",
"FIELD9":""
}
]
and what I have done thus far to change the key names:
(function() {
'use strict';
angular
.module("app.companies")
.controller('CompaniesCtrl', CompaniesCtrl);
CompaniesCtrl.$inject = ['$scope', 'CompanyFactory'];
function CompaniesCtrl($scope, CompanyFactory) {
$scope.work = "i work";
$scope.companies = CompanyFactory;
$scope.makeChart = function(company){
$scope.femaleDevs = parseInt(company.num_female_eng);
$scope.allDevs = parseInt(company.num_eng);
$scope.company = company.company;
$scope.maleDevs = $scope.allDevs - $scope.femaleDevs;
console.log($scope.maleDevs);
};
}
})();
Thank you for all of your help :) !
Maybe this should help you:
var fieldsmap = {
'FIELD1': 'key',
'FIELD2': 'company',
'FIELD3': 'team',
'FIELD4': 'num_female_eng',
'FIELD5': 'num_eng',
'FIELD6': 'percent_female_eng',
'FIELD7': 'last_updated',
'FIELD8': 'name2',
'FIELD9': 'name3'
};
function renameObjectKeys(obj) {
for (var key in fieldsmap) {
if (obj.hasOwnProperty(key) && fieldsmap.hasOwnProperty(key)) {
obj[fieldsmap[key]] = obj[key]; //copy the key into new key
delete(obj[key]); // delete old key
}
}
}
myArray.forEach(function(object) {
renameObjectKeys(object);
});
I have a wrapper function where I use a variable dataObject. I have an action to trigger some outside functions within the wrapper function.
function wrapper() {
var dataObject;
var jsonPath = "dataObject[0]['Set1'][0]['Attribute1']";
eval('outsideFunction(dataObject, jsonPath)');
}
function outsideFunction(dataObject, jsonPath) {
dataObject[0]['Set1'][0]['Attribute1'] = 'asde'; //This sets the value to dataObject in the wapper
var attrVal = '123';
eval("jsonPath = attrVal"); //This doesn't set value to dataObject in the wrapper but in the local dataObject
}
Why is there a difference in the action of direct assign and assigning using eval?
According to your structure of data[0]['Set1'][0]['Attribute1'], which can be written as data[0].Set1[0].Attribute1, here is code, but I think you don't quite understand how many sets you were asking for.
var wrapper, outsideFunction;
wrapper = function(){
someOb = {};
var data = [
{
Set1: [
{
Attribute1: null, // we will change null to 'asdf' below
},
],
},
];
outsideFunction(data, someOb);
console.log( someOb.newProp, someOb.dumb );
// outputs 'hehehehe', undefined
};
outsideFunction = function(data, blah) {
data[0].Set1[0].Attribute1 = 'asdf';
//blah is a reference to someOb
// we can change a part of blah and it will look at the reference and change someOb
blah.newProp = 'hehehehe';
// but if we do `blah =`, then we reference a new object
// This won't affect someOb, blah will just be a different object talking about something else
blah = { dumb: false };
};
So, like I was saying, your data object is a numbered set, ( you have [0] ), then a named set (Set1), then a numbered set ( [0] ), I don't think you mean to nest so much.
numberedSet = [
{
name: 'dan',
likes: [
'coding', 'girls', 'food',
],
},
{
name: 'Sreekesh',
},
]
namedSet = {
dan: {
isPerson: true,
likes: [
'coding', 'girls', 'food',
],
},
Sreekesh: {
isPerson: true,
askedQuestion: function(){
return true;
},
}
};
numberedSet[0].name == dan; // true
numberedSet[0].likes[1] == 'girls'; // true
namedSet.dan.isPerson == true; // true
namedSet.Sreekesh.askedQuestion(); // true
I have an external file people.json. How I can convert it to a javascript array with json syntax?
this is the people.json content:
{
"1":{
"Name":"Jhon",
"Surname":"Kenneth",
"mobile":329129293,
"email":"jhon#gmail.com"
},
"2":{
"Name":"Thor",
"Surname":"zvalk",
"mobile":349229293,
"email":"thor#gmail.com"
},
"3":{
"Name":"Mila",
"Surname":"Kvuls",
"mobile":329121293,
"email":"mila#gmail.com"
}
}
I want an array with this format
var person = [
{ "name":"jhon" , "surname":"kenneth", "mobile":329129293, "email":"jhon#gmail.com"},
{ "Name":"Thor", "Surname":"zvalk", "mobile":349229293, "email":"thor#gmail.com" },
{ "Name":"Mila", "Surname":"Kvuls", "mobile":329121293, "email":"mila#gmail.com"}
];
I tried with the next code, but it doesnt worker:
var person;
$.getJSON('people.json', function (json) {
person[]= json
});
By the way, the file contacts.json is in my server.
Can use jQuery $.map()
var newArray=$.map( originalObject, function(item){
return item;
})
DEMO: http://jsfiddle.net/qmfn2/
Try like this:
$.getJSON('people.json', function (json) {
var people = [];
for (var key in json) {
if (json.hasOwnProperty(key)) {
var item = json[key];
people.push({
name: item.Name,
surname: item.Surname,
mobile: item.mobile,
email: item.email
});
}
}
// at this stage the people object will contain the desired output
});
First you will need to fetch the JSON file using an AJAX request. Then iterate through the received JSON object and add each property to an array.
function convertToArray (receivedObj) {
var array = [], key;
for (key in receivedObj) {
array.push(receivedObj[key]);
}
return array;
}
$.getJSON('people.json', function (json) {
var array = convertToArray(json);
});
Hope this helps!
Like this:
var array = $.map($.parseJSON(data), Object);
http://jsfiddle.net/mXFKL/
$.getJSON('people.json', function (json) {
var array = convertToArray(json);
});