Hi i'm trying to make an Object from and array of objects and other objects for a customs final object (example in code) . Iv'e tried to do forEach on the array and create a new object and push it to the final array but had no luck. the numbers in snapObj could have the digit that's not the first in the object (digit0 could be digit1...) in dataArr this makes it hard for me to find the correct one and represent as needed. any recommendations?
var dataArr = {};
//First array of objects
var arrayContactsWithNames = [{
"digits0": "5555648583",
"digits1": "4155553695",
"name": "Kate Bell",
}, {
"digits0": "5554787672",
"digits1": "4085555270",
"digits2": "4085553514",
"name": "Daniel Higgins Jr.",
}, {
"digits0": "8885555512",
"digits1": "8885551212",
"name": "John Appleseed",
}, {
"digits0": "5555228243",
"name": "Anna Haro",
}, {
"digits0": "5557664823",
"digits1": "7075551854",
"name": "Hank M. Zakroff",
}, {
"digits0": "5556106679",
"name": "David Taylor",
}];
// Second object
var snapObj = {
"5556106679": "test 1",
"7075551854": "test 2",
"8885551212": "test 1"
};
/* This is what I want to get:
var dataArr = [{
"test 1": {
"5556106679": "David Taylor",
"8885551212": "John Appleseed"
}
}, {
"test 2": Object {
"7075551854": "Hank M. Zakroff",
}
}]
*/
// This is what I tried
arrayContactsWithNames.forEach((i) => {
if (i in snapObject) {
const newObj = Object.assign({snapObject[i],{ name },{digits${i}}});
dataArr.push(newObj);
}
});
The logic is to first create a Object dictionary of the form number:name and use it for lookup from the second object. This is most optimal since it only takes O(1) to lookup a key in an object.
var arrayContactsWithNames = [{
"digits0": "5555648583",
"digits1": "4155553695",
"name": "Kate Bell",
}, {
"digits0": "5554787672",
"digits1": "4085555270",
"digits2": "4085553514",
"name": "Daniel Higgins Jr.",
}, {
"digits0": "8885555512",
"digits1": "8885551212",
"name": "John Appleseed",
}, {
"digits0": "5555228243",
"name": "Anna Haro",
}, {
"digits0": "5557664823",
"digits1": "7075551854",
"name": "Hank M. Zakroff",
}, {
"digits0": "5556106679",
"name": "David Taylor",
}];
var snapObj = {
"5556106679": "test 1",
"7075551854": "test 2",
"8885551212": "test 1"
};
let parsedArr = arrayContactsWithNames.reduce((acc,{name,...digits}) => {
Object.values(digits).forEach(digit => { acc[digit] = name });
return acc;
}, {}); // create a { number : name } mapping with some es6 magic. Refer Object destructuring and spread operator to know how the digit0,digit1 etc are extracted.
// console.log(parsedArr)
let parsedObj = Object.keys(snapObj).reduce((acc,num) => {
let val = snapObj[num]
if(!acc[val])
acc[val] = {}
acc[val][num] = parsedArr[num]; // use the lookup object with the number
return acc;
},{}); // A simple reducer to create a new object in the desired shape.
console.log(parsedObj);
If I understand correctly what you want, consider this sample:
const data = {}
const snap = {
'5556106679': 'test 1',
'7075551854': 'test 2',
'8885551212': 'test 1'
}
const objects = [
{
'digits0': '5555648583',
'digits1': '4155553695',
'name': 'Kate Bell',
},
{
'digits0': '5554787672',
'digits1': '4085555270',
'digits2': '4085553514',
'name': 'Daniel Higgins Jr.',
},
{
'digits0': '8885555512',
'digits1': '8885551212',
'name': 'John Appleseed',
},
{
'digits0': '5555228243',
'name': 'Anna Haro',
},
{
'digits0': '5557664823',
'digits1': '7075551854',
'name': 'Hank M. Zakroff',
},
{
'digits0': '5556106679',
'name': 'David Taylor',
}]
for (const key in snap)
{
if (!data[snap[key]])
{
data[snap[key]] = {}
}
for (const object of objects)
{
for (const i in object)
{
if (object[i] === key)
{
data[snap[key]][key] = object.name
break
}
}
}
}
document.querySelector('textarea').value = JSON.stringify(data, null, ' ')
<textarea cols="50" rows="10"></textarea>
Related
I'm trying build a tree from a flat list, and I know I'm missing something that would make this much easier and faster. I've tried several approaches. The latest being the function I've posted below.
The flat list that looks like this:
var input = [
{
"Parent Category": "Agricultural Feed + Seed",
Category: "Agricultural Feed + Seed",
Name: "Agfinity"
},
{
"Parent Category": "Agricultural Feed + Seed",
Category: "Agricultural Feed + Seed",
Name: "Agland Co-op"
},
{
"Parent Category": "Agricultural Feed + Seed",
Category: "Agricultural Equipment",
Name: "Agri Supply"
},
{
"Parent Category": "Agricultural Equipment",
Category: "Tractors",
Name: "Agway"
},
{
"Parent Category": "Agricultural Equipment",
Category: "Tractors",
Name: "Agway2"
},
{
"Parent Category": "Travel",
Category: "Travel",
Name: "Amtrak"
},
{
"Parent Category": "Travel",
Category: "Accessories",
Name: "Bentley Leathers & Luggage"
}
];
From this list I'm trying to build a tree that looks like this:
[
{
"label": "Agricultural Feed + Seed",
"children": [
{
"label": "Agfinfity"
},
{
"label": "Agland Co-op"
},
{
"label": "Agricultural Equipment",
"children": [
{
"label": "Agri Supply"
"children": [
{
"label": "Tractors",
"children": [
{
"label": "Agway"
},
{
"label": "Agway2"
}
]
}
]
}
]
}
]
},
{
"label": "Travel",
"children": [
{
"label": "Amtrak"
},
{
"label": "Acessories",
"children": [
{
"label": "Bentley Leathers & Luggage"
},
}
]
}
];
I have a function like this that almost works, but I know it's not the right approach.
function formatBrandNames(rawBrands) {
let output = [];
for (let i = 0; i < rawBrands.length; i++) {
// Parent Category
if (!output.find(v => v.label === rawBrands[i]["Parent Category"])) {
output.push({
label: rawBrands[i]["Parent Category"],
children: []
});
}
// Category
let parentCat = output.find(v => v.label === rawBrands[i]["Parent Category"]);
if (rawBrands[i]["Category"] === parentCat.label) {
const name = trimBrandNumbers(rawBrands[i]["Name"]);
parentCat.children.push({ label: name });
continue;
}
if (!parentCat.children.find(v => v.label === rawBrands[i]["Category"])) {
parentCat.children.push({ label: rawBrands[i]["Category"], children: [] });
}
// Name
let cat = parentCat.children.find(v => v.label === rawBrands[i]["Category"]);
const name = trimBrandNumbers(rawBrands[i]["Name"]);
cat.children.push({ label: name });
}
return output;
}
Any help or insight on this would be greatly appreciated.
The logic can be simplified to
If the node has no parent category, it is one of the root categories
Find the Parent by it's category, then add the node to the parent's children
If the parent does not exist, create it.
function toTree(nodes) {
const roots = [];
const byCategory = new Map();
for(const { Name: label, ["Parent Category"]: parent, Category: category } of nodes) {
const node = { label, children: [] };
if(byCategory.has(category)) {
byCategory.get(category).children.push(node);
} else {
const categoryObj = {
label: category,
children: [node]
};
byCategory.set(category, categoryObj);
if(parent === category) {
roots.push(categoryObj);
} else if(byCategory.has(parent)) {
byCategory.get(parent).children.push(categoryObj);
} else {
byCategory.set(parent, { label: parent, children: [categoryObj] });
}
}
}
return roots;
}
In Javascript, how to retrieve an object in an array by one of its property ?
Hi all,
let's assume that we have the below :
"Attributes":[
{
"Name":"Brief",
"Value":"This skirt was fabriced from ...."
},
{
"Name":"Details",
"Value":"Measurements and Pictures are real"
},
{
"Name":"SKUNumber",
"Value":"12345678"
}
]
What I need to do is to get the value of "Value" based on "Name"..
For example :
console.log(Attributes.Brief) ==> "This skirt was fabriced from ...."
So I need a function to help doing that
Note that I don't want to use the index of the object, because its order may changed.
Thank you
Well, it's always better to show what you have attempted rather than just asking..
You can use Array.find to achieve this
let Attributes = [
{
"Name":"Brief",
"Value":"This skirt was fabriced from ...."
},
{
"Name":"Details",
"Value":"Measurements and Pictures are real"
},
{
"Name":"SKUNumber",
"Value":"12345678"
}
]
function getValueByName(name) {
return Attributes.find(d => d.Name.toLowerCase() == name.toLowerCase()).Value
}
console.log(getValueByName('Brief'))
console.log(getValueByName('details'))
console.log(getValueByName('SKUNumber'))
One option you have is to use Array.prototype.filter:
const d = [{
"Name": "Brief",
"Value": "This skirt was fabriced from ...."
},
{
"Name": "Details",
"Value": "Measurements and Pictures are real"
},
{
"Name": "SKUNumber",
"Value": "12345678"
}
]
console.log(d.filter(x=>x.Name==="Brief")[0].Value)
You can also make it more generic:
const d = [{
"Name": "Brief",
"Value": "This skirt was fabriced from ...."
},
{
"Name": "Details",
"Value": "Measurements and Pictures are real"
},
{
"Name": "SKUNumber",
"Value": "12345678"
}
]
const getValOfXfromArrByValOfY = (arr, x, y, val) => arr.find(z => z[y] === val)[x]
console.log(getValOfXfromArrByValOfY(d, 'Value', 'Name', 'SKUNumber'))
You could use a Proxy with a getter for the key, which returns a find of the object with the value.
var object = { attributes: [{ Name: "Brief", Value: "This skirt was fabriced from ...." }, { Name: "Details", Value: "Measurements and Pictures are real" }, { Name: "SKUNumber", Value: "12345678" }] },
attributes = new Proxy(
object.attributes,
{ get: (array, prop) => (array.find(({ Name }) => Name === prop) || {}).Value }
);
console.log(attributes.Brief);
console.log(attributes.SKUNumber);
You can use javascript find function see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find see bellow sample code:
var Attributes =[
{
"Name":"Brief",
"Value":"This skirt was fabriced from ...."
},
{
"Name":"Details",
"Value":"Measurements and Pictures are real"
},
{
"Name":"SKUNumber",
"Value":"12345678"
}
]
var found = Attributes.find(function(element) {
return element.Name == "Details";
});
console.log(found.Value); //output : Measurements and Pictures are real
I am building a select dropdown input for a webpage. I want to make a 'popular' options group which appears at the top of the dropdown.
I am working with data in the following structure.
I need to find a way to reorder the items inside the people array based on their name.
For example moving:
pogo-stick from toys[2] -> toys[0]
cards from toys[3] to toys [2]
I will have an array of popular toys such as:
popularToys: [
"cards", "pogo-stick"
]
How can I iterate through the array of objects and move them in to the new order?
Data:
{
"toys": [
{
"name": "car",
"price": "10"
},
{
"name": "duck",
"price": "25"
},
{
"name": "pogo-stick",
"price": "60"
},
{
"name": "cards",
"price": "5"
}
]
}
Use forEach() loop where you can find the index of the toy object and swap:
var popularToys = [
"cards", "pogo-stick"
]
var data = {
"toys": [
{
"name": "car",
"price": "10"
},
{
"name": "duck",
"price": "25"
},
{
"name": "pogo-stick",
"price": "60"
},
{
"name": "cards",
"price": "5"
}
]
};
popularToys.forEach(function(toy, index){
var toyObjIndex = data.toys.findIndex(x => x.name==toy);
//swap
var tempObj = data.toys[toyObjIndex];
data.toys[toyObjIndex] = data.toys[index];
data.toys[index] = tempObj;
});
console.log(data);
Using a combination of map and filter we are able to split the required logic into to methods (Maybe more readable)
Popular() returns a filtered Array of any of the toy items that have a name property that corresponds with the current name in the iteration of popular
Rest() returns a filtered Array of toys where the name property of the toy in the iteration does not exist in the Array of String in popular
const toys = [
{
name: 'car',
price: '10'
},
{
name: 'exception',
price: '999999'
},
{
name: 'duck',
price: '25'
},
{
name: 'pogo-stick',
price: '60'
},
{
name: 'cards',
price: '5'
},
{
name: 'another !exception',
price: '100000'
},
{
name: 'pogo-stick',
price: 'A MILLION POUNDS'
},
{
name: 'duck',
price: '100'
}
]
const popular = [
'cards',
'pogo-stick',
'car',
'duck'
]
const Popular = () => {
return [].concat(...popular.map(n => toys.filter(({name}) => name === n)))
}
const Rest = () => toys.filter(({name}) => popular.indexOf(name) === -1)
let ordered = [].concat(...Popular(), ...Rest())
console.log(ordered)
You could use a custom sort function
var popularToys = [
"cards", "pogo-stick"
]
var data = {
"toys": [
{
"name": "car",
"price": "10"
},
{
"name": "duck",
"price": "25"
},
{
"name": "pogo-stick",
"price": "60"
},
{
"name": "cards",
"price": "5"
}
]
};
function popularFirst(a, b) {
var aIsPopular = popularToys.indexOf(a.name) > -1;
var bIsPopular = popularToys.indexOf(b.name) > -1;
if (aIsPopular) {
// b could be popular or not popular, a still comes first
return -1;
} else if (bIsPopular) {
// a isnt popular but b is, change the order
return 1;
} else {
// no change
return 0;
}
}
console.log(data.toys.sort(popularFirst));
function compare(a,b) {
if (a.name < b.name)
return -1;
if (a.name > b.name)
return 1;
return 0;
}
toys.sort(compare);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
I'd like to map this table's chapter_id and brother_id with the brothers and chapters table below and return the brothername and name field's respectively. Using js or jquery. I am using vuejs returning minutes array as a computed property. See below.
In sql it's be something like
select brothername from brothers where minute.brother_id = brothers.id ... and then set the brothername as the new value for brother_id
same thing goes for chapter_id:
select brothername from brothers where minute.brother_id = brothers.id ... and then set the brothername as the new value for brother_id
the resulting array or object should be:
Expected Array
[
{
"location":"UCLA",
"chapter_id":"Beta",
"brother_id":"Golpher",
"created_at":"2008-05-15 22:23:00",
"status":"Approved"
},
{ ... },
{
"location":"John's Deli",
"chapter_id":"Beta", notice the change in the array based on the ids
"brother_id":"Sheera", notice the change in the array based on the ids
"created_at":"2008-05-15 22:23:00",
"status":"Approved"
}
]
Minutes Table (original array)
[
{
"location":"UCLA",
"chapter_id":2,
"brother_id":1,
"created_at":"2008-05-15 22:23:00",
"status":"Approved"
},
{ ... },
{
"location":"John's Deli",
"chapter_id":2,
"brother_id":4,
"created_at":"2008-05-15 22:23:00",
"status":"Approved"
}
]
Chapter's Table
[
{
"id":1,
"letter_representation":"A",
"name":"Alpha",
"founded_at":"UCLA",
...
},
{ ... }
]
Brother's Table
[
{
"id":1,
"profile_id":1,
"chapter_id":1,
"brothername":"Golpher",
"firstname":"Jack",
...
},
{ ... },
{
"id":4,
"profile_id":4,
"chapter_id":1,
"brothername":"Sheera",
"firstname":"Jake",
...
}
]
Vue.js
computed: {
brothers () {
return this.$store.state.brothers
},
chapters () {
return this.$store.state.chapters
},
minutes () {
return this.$store.getters.model
}
},
I assume that you don't want to mutate objects in the original arrays with this operation.
Note You may want to handle the case where brother_id or chapter_id doesn't exist in the corresponding table. In the below example, it just sets the property value to undefined
const minutesTable = [{
"location": "UCLA",
"chapter_id": 2,
"brother_id": 1,
"created_at": "2008-05-15 22:23:00",
"status": "Approved"
}, {
"location": "John's Deli",
"chapter_id": 2,
"brother_id": 4,
"created_at": "2008-05-15 22:23:00",
"status": "Approved"
}]
const chapterTable = [{
"id": 1,
"letter_representation": "A",
"name": "Alpha",
"founded_at": "UCLA",
}]
const brotherTable = [{
"id": 1,
"profile_id": 1,
"chapter_id": 1,
"brothername": "Golpher",
"firstname": "Jack",
}, {
"id": 4,
"profile_id": 4,
"chapter_id": 1,
"brothername": "Sheera",
"firstname": "Jake",
}]
// your result
const result = minutesTable.map(m => {
const brother = brotherTable.find(b => b.id === m.brother_id)
const chapter = chapterTable.find(c => c.id === m.chapter_id)
return Object.assign({}, m, {
brother_id: brother && brother.brothername,
chapter_id: chapter && chapter.name,
})
})
console.log(result)
This should be what you need
const minutesTable = [
{
"location":"UCLA",
"chapter_id":2,
"brother_id":1,
"created_at":"2008-05-15 22:23:00",
"status":"Approved"
},
{
"location":"John's Deli",
"chapter_id":2,
"brother_id":4,
"created_at":"2008-05-15 22:23:00",
"status":"Approved"
}
]
const chapterTable =
[
{
"id":1,
"letter_representation":"A",
"name":"Alpha",
"founded_at":"UCLA",
}
]
const brotherTable = [
{
"id":1,
"profile_id":1,
"chapter_id":1,
"brothername":"Golpher",
"firstname":"Jack",
},
{
"id":4,
"profile_id":4,
"chapter_id":1,
"brothername":"Sheera",
"firstname":"Jake",
}
]
/* code starts here */
let newMinutesTable = JSON.parse(JSON.stringify(minutesTable)).map(a => {
let brother = brotherTable.find(id => id.id === a.brother_id);
let chapter = chapterTable.find(id => id.id === a.chapter_id)
if (brother) a.brother_id = brother.brothername
if (chapter) a.chapter_id = chapter.name;
return a;
})
console.log([minutesTable,newMinutesTable]);
I think you should prepare those values first just to better understanding. So I made this, let me explain in pieces.
Your input information:
var minutesTable = [{
"location": "UCLA",
"chapter_id": 2,
"brother_id": 1,
"created_at": "2008-05-15 22:23:00",
"status": "Approved"
}, {
"location": "John's Deli",
"chapter_id": 2,
"brother_id": 4,
"created_at": "2008-05-15 22:23:00",
"status": "Approved"
}],
chapterTable = [{
"id": 1,
"letter_representation": "A",
"name": "Alpha",
"founded_at": "UCLA",
}],
brotherTable = [{
"id": 1,
"profile_id": 1,
"chapter_id": 1,
"brothername": "Golpher",
"firstname": "Jack",
}, {
"id": 4,
"profile_id": 4,
"chapter_id": 1,
"brothername": "Sheera",
"firstname": "Jake",
}];
Somehow you'll be forced to take this information as variables. We will work with that.
Preparing data
Dealing with array of objects it's a litle bit complicated when you need to look for unique informations on each object from distinct arrays especially if you want to run this more than once. So instead of working with arrays of objects we can save our lifes changing that to objects of objects, where each item index must be that unique IDs. Look:
var chapters = {},
brothers = {};
chapterTable.map(function(el, i) {
chapters[el.id] = el;
});
brotherTable.map(function(el, i) {
brothers[el.id] = el;
});
Now you can easily find a chapter by chapter_id or a brother by brother_id, right? Then you can finish the problem like this:
var output = [];
minutesTable.map(function(el, i) {
var item = {
"location": el.location, // note that values are just default values, just in case
"chapter_id":"-",
"brother_id":"-",
"created_at": el.created_at,
"status": el.status
};
// PS: you need to check if that brother_id really exists!
if(brothers[el.brother_id] != undefined) {
item.brother_id = brothers[el.brother_id].brothername;
}
// PS: the same with chapters
if(chapters[el.chapter_id] != undefined) {
item.chapter_id = chapters[el.chapter_id].name;
}
output.push(item);
});
That's it. Anyway, if you can change your SQL queries, would be better to work with SQL joins and prepare your values there.
I want to change a json array keys names from upper case letters to a lower case keys as the following
[
{
"_id": "581f2749fb9b6f22308f5063",
"WorkshopId": "1",
"WorkshopTitle": "workshop1",
"WorkshopPrice": "200",
"WorkshopDescription": "workshop1 is a test workshop",
"FloorNumber": "1",
"RoomNumber": "205",
"WorkshopLanguage": "english language",
"LastOnlineRegistrationDate": "15/10/2016",
"WorkshopDate": "1/11/2016",
"WorkshopStartTime": "8:00 AM",
"WorkshopEndTime": "11:00 AM",
"WorkshopRules": "Rules will be mentioned here",
"WorkshopCapacity": "200",
"Speaker": {
"SpeakerName": "John doe",
"AboutSpeaker": "About the speaker"
}
},
{
"_id": "581f27e796915434f44cd678",
"WorkshopId": "2",
"WorkshopTitle": "workshop2",
"WorkshopPrice": "200",
"WorkshopDescription": "workshop2 is a test workshop",
"FloorNumber": "1",
"RoomNumber": "205",
"WorkshopLanguage": "english language",
"LastOnlineRegistrationDate": "15/10/2016",
"WorkshopDate": "1/11/2016",
"WorkshopStartTime": "11:00 AM",
"WorkshopEndTime": "02:00 PM",
"WorkshopRules": "Rules will be mentioned here",
"WorkshopCapacity": "200",
"Speaker": {
"SpeakerName": "Jane doe",
"AboutSpeaker": "Jane doe - About the speaker"
}
}
]
for example WorkshopId must be changed to workshopid, I have a function in node js that query a collection in mongodb and return the json :
getWorkshops: function (db, response) {
db.collection('Workshops').find().toArray(function (err, results) {
var convertedArr = [];
//convert the json.
response.send(JSON.stringify(convertedArr));
});
any help?
This will map an object's keys to lowercase:
var upperCased = [
{ ID: 1, NAME: 'Fred' },
{ ID: 2, NAME: 'Sarah' },
{ ID: 3, NAME: 'Joe' },
];
var lowerCased = upperCased.map(function(item) {
var mapped = {};
for (var key in item) {
mapped[key.toLowerCase()] = item[key];
}
return mapped;
});
https://jsfiddle.net/5ouebw4b/2/
You could to it with a custom toJSON() function:
getWorkshops: function (db, response) {
db.collection('Workshops').find().toArray(function (err, results) {
results.toJSON = function () {
var newArr = [];
for (var obj in this) {
if (!this.hasOwnProperty(obj) || 'toJSON' === obj) continue;
var newObj = {};
for (var prop in this[obj]) {
if (!this[obj].hasOwnProperty(prop)) continue;
newObj[prop.toLowerCase()] = this[obj][prop];
}
newArr.push(newObj);
}
return newArr;
};
response.send(JSON.stringify(results));
});
}