Used below JS code to get JSON response from endpoint URL. Response value returns correctly like below JSON format.
From this JSON format, i need to extract and display in array format for DATALAYER. But, below code getting output of last time instead of all JSON response items to show.
Format required:
newArray [
{
codePlan: "SSS0111",
title: "Title 1"
},
{
codePlan: "",
title: "Title 2"
},
{
codePlan: "SSS0888,CCC0222,EEE0001,DDD0009",
title: "Title 3"
}
]
But it get last item only and displays like this.
newArray [
{
codePlan: "SSS0891",
title: "Title 5"
}
]
var endpointUrl = '/data/codelisting.json';
$.get(endpointUrl, function (response) {
$.each(response.data, function (i, item) {
var dataLayerObject = {};
var newArray = [
{
codePlan: item.codePlan,
title: item.title
}
];
dataLayerObject = {
arrayParent: {
newArray : [...newArray]
}
};
DTM.setDataLayer(dataLayerObject);
});
});
{
"total": 5,
"data":[
{
"title":"Title 1",
"description":"description 1"
"codePlan":[
"SSS0111"
]
},
{
"title":"Title 2",
"description":"description 2"
"codePlan":[]
},
{
"title":"Title 3",
"description":"description 3"
"codePlan":[
"SSS0888",
"CCC0222",
"EEE0001",
"DDD0009"
]
},
{
"title":"Title 4",
"description":"description 4"
"codePlan":[
"SSS0897"
]
},
{
"title":"Title 5",
"description":"description 5"
"codePlan":[
"SSS0891"
]
}
]
}
The problem with var newArray = [ it updates the newArray value with a new value each time in a loop .. So you need to define it before .each() var newArray = []; and let .each() add a new value to it newArray[i] =
$.get(endpointUrl, function (response) {
var newArray = []; //<<<<<<<<<<< here
$.each(response.data, function (i, item) {
var dataLayerObject = {};
newArray[i] = [ // <<<<<< use newArray[i] here
{
codePlan: item.codePlan,
title: item.title
}
];
dataLayerObject = {
arrayParent: {
newArray : [...newArray]
}
};
DTM.setDataLayer(dataLayerObject);
});
var response = [
{
codePlan: "SSS0111",
title: "Title 1"
},
{
codePlan: "",
title: "Title 2"
},
{
codePlan: "SSS0888,CCC0222,EEE0001,DDD0009",
title: "Title 3"
}
];
var newArray = []
$.each(response , function(i , item){
newArray[i] = [{
codePlan: item.codePlan,
title: item.title
}]
});
console.log(newArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Related
I am trying to convert a 2d array into a json object using a key map.
The key map looks like
var keys = ['id', 'title', 'customer.id', 'customer.name', 'customer.phone.home', 'customer.phone.mobile' ];
and the data is
var data = [
[1, 'Task 1', 'C1', 'Customer 1', '999', '8888'],
[2, 'Task 2', 'C2', 'Customer 2', '333', '5555']
];
Output JSON should be
var output = [
{
"id":1,
"title":"Task 1",
"customer":{
"id":"C1",
"name":"Customer 1",
"phone":{
"home":"999",
"mobile":"8888"
}
}
},
{
"id":2,
"title":"Task 2",
"customer":{
"id":"C2",
"name":"Customer 2",
"phone":{
"home":"333",
"mobile":"5555"
}
}
}
];
I am trying to do it something like but I am not good here making smerecursion etc. Could anyone help please?
function arrToJSON(headers, data){
var output = [];
data.forEach(row, index){
var cObj = {};
headers.forEach(header, itemIndex){
var headerParts = header.split('.');
// NOt sure what to do here
}
}
}
You can easily achieve the result using map and reduce in js.
createObj(acc, curr.split("."), 0, o[index]);
is the function that is used in recursion and that is what you're looking for.
Arguments
createObj(
acc, // object in which you want to add value
curr.split("."), // send path as an array
0, // current index in path, initially zero
o[index] // value to be assigned
);
var keys = [
"id",
"title",
"customer.id",
"customer.name",
"customer.phone.home",
"customer.phone.mobile",
];
var data = [
[1, "Task 1", "C1", "Customer 1", "999", "8888"],
[2, "Task 2", "C2", "Customer 2", "333", "5555"],
];
function createObj(obj, arr, index, value) {
if (index === arr.length - 1) obj[arr[index]] = value;
else {
if (!obj[arr[index]]) obj[arr[index]] = {};
createObj(obj[arr[index]], arr, index + 1, value);
}
}
const result = data.map((o) => {
return keys.reduce((acc, curr, index) => {
createObj(acc, curr.split("."), 0, o[index]);
return acc;
}, {});
});
console.log(result);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
You can use simply use destructure and spread operator with reduce.
var data = [
[1, "Task 1", "C1", "Customer 1", "999", "8888"],
[2, "Task 2", "C2", "Customer 2", "333", "5555"],
];
const buildObject = (arr = []) => {
return arr.reduce((acc, [id, title, cid, name, home, mobile]) => {
const row = {
id,
title,
customer: { id: cid, name, phone: { home, mobile } },
};
return acc.concat(row);
}, []);
};
console.log(buildObject(data));
I am trying to get the key from the value of the Object. I have the following array:
["Test 91", "Test 92", "Demo 1", "Demo 2"]
And I have one object:
{
D123_EMG: {
value: "Test 91",
isArchived: true
}
D21: {
value: "Test 92",
isArchived: false
}
Z6200_EMO: {
value: "Demo 1",
isArchived: true
}
G211_GTH: {
value: "Demo 2",
isArchived: false
}
}
So how can I get key as D123_EMG if the value is Test 91?
I tried this, but not getting proper response
var data = Object.keys(objectData);
var keys = []
for(var i = 0; i < array.length; i++){
for(var j = 0; j < data.length; j++){
if(array[i] === objectData[data[j].value) {
keys.push(objectData[data[j])
}
}
}
Also, can it be optimized since I used two loops or one-liner approach?
You can use filter() in this way:
const values = ["Test 91", "Test 92", "Demo 1", "Demo 2"];
const data = {
D123_EMG: {
value: "Test 91",
isArchived: true
},
D21: {
value: "Test 92",
isArchived: false
},
Z6200_EMO: {
value: "Demo 1",
isArchived: true
},
G211_GTH: {
value: "Demo 2",
isArchived: false
}
}
const keysFound = Object.keys(data).filter(key => values.includes(data[key].value));
console.log(keysFound); // ["D123_EMG", "D21", "Z6200_EMO", "G211_GTH"];
This isn't really related to react. Someone else may have a cleaner solution, but here is one that will work if I understand your question correctly:
let data = {
D123_EMG: {
value: "Test 91",
isArchived: true
},
D21: {
value: "Test 92",
isArchived: false
},
Z6200_EMO: {
value: "Demo 1",
isArchived: true
},
G211_GTH: {
value: "Demo 2",
isArchived: false
}
}
let name = '';
Object.entries(data).forEach((v) => {
// if the object value matches, set the name variable to the key
if (v[1].value == 'Test 91') {
name = v[0];
}
})
console.log(name)
I like to use .reduce() which in this case also works. Read from the MDN documentation:
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.
And you can combine it with Object.entries() where the documentation states:
The Object.entries() method returns an array of a given object's own enumerable string-keyed property [key, value] pairs, in the same order as that provided by a for...in loop. (The only important difference is that a for...in loop enumerates properties in the prototype chain as well).
See the working solution what I made:
const data = { D123_EMG: { value: "Test 91", isArchived: true }, D21: { value: "Test 92", isArchived: false }, Z6200_EMO: { value: "Demo 1", isArchived: true }, G211_GTH: { value: "Demo 2", isArchived: false } };
const filterValue = 'Test 91';
const entries = Object.entries(data);
const result = entries.reduce((a, c) => c[1].value === filterValue ? c[0] : a, '');
console.log(result);
I hope this helps!
If you're experiencing this problem in a state management store, then this is a sign that the store is not properly designed. Without more information, I can't really recommend an improvement on how to redesign your state.
So, barring a redesign of your state, you may consider creating a map by value like so:
const byValue = Object.keys(data).reduce((accumulator, currentKey) => {
const currentObject = data[currentKey];
currentObject.key = currentKey;
accumulator[currentObject.value] = currentObject;
return accumulator;
}, {});
This produces a map that looks like this:
{
"Test 91": { "value": "Test 91", "isArchived": true, "key": "D123_EMG" },
"Test 92": { "value": "Test 92", "isArchived": false, "key": "D21" },
"Demo 1": { "value": "Demo 1", "isArchived": true, "key": "Z6200_EMO" },
"Demo 2": { "value": "Demo 2", "isArchived": false, "key": "G211_GTH" }
}
With this, you use the value as the lookup key:
const test91 = byValue["Test 91"]
...
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;
}
I have this array of an object, I need to select the 'default_image' or 'label' or 'html' values using loop. But unable to do this.
var panel_array = [{
"Panel":{
"Panel_1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"Panel_2":{
"default_image":"<img src='"+themeUrl+"/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
"List":{
"l1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"l2":{
"default_image":"<img src='"+themeUrl+"/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
}]
I tried this and it prints all the values but how to access single value like if i want only 'label' or i want only 'html':
panel_array.map(data => {
for (var items in data) {
for(var dt in data[items]){
var ab = data[items];
for(var xx in ab) {
var ii = ab[xx];
for(var oo in ii){
console.log(ii[oo]);
}
}
}
}
})
Just add an if clause:
var panel_array = [{
"Panel":{
"Panel_1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"Panel_2":{
"default_image":"<img src='/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
"List":{
"l1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"l2":{
"default_image":"<img src='/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
}]
panel_array.map(data => {
for (var items in data) {
for(var dt in data[items]){
var ab = data[items];
for(var xx in ab) {
var ii = ab[xx];
for(var oo in ii){
if (oo == "label" || oo == "html") console.log(ii[oo]);
}
}
}
}
})
You can use forEach of array, Object.keys and Object.values()
const panel_array = [{
"Panel": {
"Panel_1": {
"default_image": "http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label": "Panel List 1",
"html": "<dl class='drop_list1'></dl>"
},
"Panel_2": {
"default_image": "<img src='/prepengine/images/Interactive-items/panel2.png'",
"label": "Panel List 2",
"html": "<dl class='drop_list2'></dl>"
}
},
"List": {
"l1": {
"default_image": "http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label": "Panel List 1",
"html": "<dl class='drop_list1'></dl>"
},
"l2": {
"default_image": "<img src='/prepengine/images/Interactive-items/panel2.png'",
"label": "Panel List 2",
"html": "<dl class='drop_list2'></dl>"
}
},
}];
panel_array.forEach(o => {
Object.keys(o).forEach(key => {
Object.values(o[key]).forEach(item => {
//you can access whatever you need
console.log(item);
});
});
});
let themeUrl = 'MockmyUrl';
let panel_array = [{
"Panel":{
"Panel_1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"Panel_2":{
"default_image":"<img src="+themeUrl+"/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
"List":{
"l1":{
"default_image":"http://s3.amazonaws.com/jigyaasa_content_static/interactive_item/panel_1.png",
"label":"Panel List 1",
"html":"<dl class='drop_list1'></dl>"
},
"l2":{
"default_image":"<img src='"+themeUrl+"/prepengine/images/Interactive-items/panel2.png'",
"label":"Panel List 2",
"html":"<dl class='drop_list2'></dl>"
}
},
}];
let images = [];
let lables = [];
let htmls = [];
let output = panel_array.forEach((ele) => {
Object.values(ele).forEach((ele2) => {
Object.values(ele2).forEach((ele3) => {
let {default_image, label, html} = ele3;
images.push(default_image);
lables.push(label);
htmls.push(html);
});
});
});
console.log(images);
console.log('----------------');
console.log(lables);
console.log('----------------');
console.log(htmls);
I have an array that contains different clothes and the type of the cloth. For example, I may have a specific shirt that belongs to the shirts category. What I want to do is get all the types from an array and ignore any duplicate entries. So if I have 3 shirts and 2 trousers, I will only get 1 shirt and 1 trouser.
array = [
{
name: "test 1",
type: "shirt"
},
{
name: "test 2",
type: "shirt"
},
{
name: "test 3",
type: "trousers"
},
{
name: "test 4",
type: "trousers"
}
];
var categories = {};
for(var i = 0, len = array.length; i < len; i++) {
if(categories.indexOf(array[i].type) > -1) {
console.log('Duplicate type');
}
else {
console.log('New type');
categories.push(array[i].type);
}
}
But I end up getting TypeError: categories.indexOf is not a function.
Pretty short solution using ES6 Set object:
The Set object lets you store unique values of any type, whether
primitive values or object references.
var categories = new Set();
array.forEach((o) => categories.add(o.type));
categories = [...categories]; // Set to Array transformation
console.log(categories); // ["shirt", "trousers"]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
You need an array for categories, not an object.
var categories = [];
array = [
{
name: "test 1",
type: "shirt"
},
{
name: "test 2",
type: "shirt"
},
{
name: "test 3",
type: "trousers"
},
{
name: "test 4",
type: "trousers"
}
];
var categories = [];
for(var i = 0, len = array.length; i < len; i++) {
if(categories.indexOf(array[i].type) > -1) {
console.log('Duplicate type');
}
else {
console.log('New type');
categories.push(array[i].type);
}
}
console.log(categories);
This happens because you define categories as object literal ({}), rather than an array ([]):
// --------------vv
var categories = {};
Your issue is that you are trying to invoke .push method on an object but the method is available only on Array. You need to make categories an array in order to push to it.
As an alternative, you can use pure function without any mutations using Array.prototype.reduce() to reduce the array of duplicate objects to unique ones:
var array = [
{
name: "test 1",
type: "shirt"
},
{
name: "test 2",
type: "shirt"
},
{
name: "test 3",
type: "trousers"
},
{
name: "test 4",
type: "trousers"
}
];
function unique(input) {
return input.reduce(function (acc, current) {
if (acc.indexOf(current.type) > -1) {
return acc
} else {
return acc.concat([current.type]);
}
}, [])
}
var categories = unique(array);
console.log(categories);
If you want to see the result of every row then I think first implementation could be the answer but if you want just the categories then using map make it simple.
array = [
{ name: "test 1", type: "shirt" },
{ name: "test 2", type: "shirt" },
{ name: "test 3", type: "trousers" },
{ name: "test 4", type: "trousers" }
];
// --------------------------------------
var categories = [];
array.forEach(v => {
if (this[v.type])
return console.log('Duplicate type');
console.log('New type');
this[v.type] = true;
categories.push(v.type);
}, {});
console.log(categories);
// --------------------------------------
var map = new Map;
array.forEach(v => map.set(v.type, v.type));
categories = [...map.keys()];
console.log(categories);