compare two different arrays in javascript - javascript

can any one help in this i am trying to compare two different arrays for pushing values when comparision is equal. below are my two(imageslide.therapy),totalValues arrays and i want compare names like cats and dogs. if condition is true then i need to push their images urls.
var imageslide = {
"therapy": [
{
"name": "cats",
"images": [
{ "url": "cat/firstimg.jpg" },
{ "url": "cat/secondimg.jpg" },
{ "url": "cat/thirdimg.jpg" },
{ "url": "cat/fourthimg.jpg" }
]
},
{
"name": "dogs",
"images": [
{ "url": "dog/firstdog.jpeg" },
{ "url": "dog/seconddog.jpg" },
{ "url": "dog/thirddog.jpg" },
{ "url": "dog/fourthdog.jpg" }
]
},
]
}
var totalValues = ["cats","dogs"];
and i tried like below
var imageArray = imageslide.therapy
function compare(imageArray,totalValues ){
imageArray.forEach((e1)=>totalValues.forEach((e2)=>{
if(e1.name==e2){
console.log(e1.name,",",e2)
}
})

For what I understand from your question here is the answer. Please forgive me I don't know much about arrow function so I wrote it in simple javascript.
var imageslide = {
"therapy": [
{
"name": "cats",
"images": [
{ "url": "cat/firstimg.jpg" },
{ "url": "cat/secondimg.jpg" },
{ "url": "cat/thirdimg.jpg" },
{ "url": "cat/fourthimg.jpg" }
]
},
{
"name": "dogs",
"images": [
{ "url": "dog/firstdog.jpeg" },
{ "url": "dog/seconddog.jpg" },
{ "url": "dog/thirddog.jpg" },
{ "url": "dog/fourthdog.jpg" }
]
},
]
}
var totalValues = ["cats","dogs"];
var imageArray = imageslide.therapy
function compare(imageArray,totalValues ){
for(var i=0;i<imageArray.length;i++){
for(var j=0;j<totalValues.length;j++){
if(totalValues[j]=imageArray[i].name){
console.log(imageArray[i].name+"=="+totalValues[j]);
//imageArray[i].images.push({"url": "https://hexasoft.io"});
//break;
return imageArray[i].images;
}
}
}
//printResult(imageArray);
return [];
}
function printResult(resultArray){
for(var i=0;i<resultArray.length;i++) {
console.log(resultArray[i].name);
for(var j=0;j<resultArray[i].images.length;j++){
console.log(resultArray[i].images[j]);
}
}
}
images = compare(imageArray, totalValues);
if(images.length > 0){
for(var i=0;i<images.length; i++){
images[i].push({"url": "your url"});
}
}

Check out the javascript filter function (Link for the docs).
In your case, you want to do something like this:
function getImagesByAnimalName(animal_name){
var imageArray = imageslide.therapy;
var animalImages = imageArray.filter(animalData => {
return animalData.name === animal_name;
})
return animalImages[0].images;
}

Try it like this. The function will return URLs for each element in totalValues array.
var totalValues = ["cats"];
var slides = imageslide.therapy;
function comp(slides, totalValues ){
let retVal;
for( val of totalValues ) {
for( thisTh of slides ) {
if( thisTh.name == val ){
retVal = thisTh.images;
}
}
}
return retVal;
}

The following will create pics, a flat array of image URLs, if this is what you want:
var pics=[].concat(...imageslide.therapy.map(el=>{
if (totalValues.indexOf(el.name)>-1)
return el.images.map(e=>e.url)}))
console.log(pics);

function compare(imageArray, totalValues) {
for (var a = 0; a < imageArray.length; a++) {
for (var j = 0; j < totalValues.length; j++) {
if (totalValues[j] == imageArray[a].name) {
allValues.push(imageArray[a].images);
for (var i = 0; i < allValues.length; i++) {
for(var j = 0; j < allValues[i].length; j++){
buildSlide(allValues[i][j].url);
}
}
}
}
}
displaySlides(slide_index);
}

Related

Is there a quick way to add to a JSON the elements of another similar JSON?

I want to use a location-based API for putting markers on a map project. This API returns a JSON containing data about the 50 closest scooters of a GET-provided location.
I want to combine the results of several of these JSONs, into one that would contain all the data of the scooters in a greater area (if possible without duplicates)
I already tried JSON1.concat(JSON2); without much success, as you can see in the code below.
var latitudes = makeArr(48.810067,48.900169,30);
var longitudes = makeArr(2.248876,2.42397,30);
var allskoots= new Array();
for (var i = 0; i < latitudes.length; i++) {
for (var j = 0; j < longitudes.length; j++) {
var req = new XMLHttpRequest();
req.open("GET", "https://api-prod.ibyke.io/v2/boards?latitude="+latitudes[i]+"&longitude="+longitudes[j]);
req.responseType = 'json';
req.send();
req.onload = function() {
var allscoots=allscoots.concat(req.response);
}
}
}
A single API answer looks like this :
{"result":0,
"items":[{"param1":value1_0,
"param2":value2_0},
{"param1":value1_1,
"param2":value2_1}
...
]
}
So I'd want to be able to get from 2 of these JSONs, for instance:
{"result":0,
"items":[{"param1":value1_0,
"param2":value2_0},
{"param1":value1_1,
"param2":value2_1}
]
}
and
{"result":0,
"items":[{"param1":value1_1,
"param2":value2_1},
{"param1":value1_2,
"param2":value2_2}
]
}
the following result :
{"result":0,
"items":[{"param1":value1_0,
"param2":value2_0},
{"param1":value1_1,
"param2":value2_1}
{"param1":value1_2,
"param2":value2_2}
]
}
Is there a simple way to do it in Javascript ?
Rudimentary answer and could be optimized, but is this what you are looking for?
var r1 = {
"result": 0,
"items": [{
"param1": "value1_0",
"param2": "value2_0"
},
{
"param1": "value1_1",
"param2": "value2_1"
}
]
}
var r2 = {
"result": 0,
"items": [{
"param1": "value1_1",
"param2": "value2_1"
},
{
"param1": "value1_2",
"param2": "value2_2"
}
]
}
var merged = {
"result": 0,
"items": r1.items.concat(r2.items.filter(x => !contains(r1.items, x)))
}
// assuming no duplicates in r2.items
/*
// in case of duplicates
merged.items = r1.items;
for (var i in r2.items) {
if (!contains(merged.items, r2.items[i]))
merged.items.push(r2.items[i]);
}
*/
console.log(merged);
function contains(array, elem) {
for (var i in array) {
if (isEquivalent(array[i], elem)) return true;
}
return false
}
// credit to http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html
function isEquivalent(a, b) {
var aProps = Object.getOwnPropertyNames(a);
var bProps = Object.getOwnPropertyNames(b);
if (aProps.length != bProps.length) {
return false;
}
for (var i = 0; i < aProps.length; i++) {
var propName = aProps[i];
if (a[propName] !== b[propName]) {
return false;
}
}
return true;
}
Solve your JSON. Run my script. Hope you get it.
var r1 = {
"result": 0,
"items": [{
"param1": "value1_0",
"param2": "value2_0"
},
{
"param1": "value1_1",
"param2": "value2_1"
}
]
}
var r2 = {
"result": 0,
"items": [{
"param1": "value1_1",
"param2": "value2_1"
},
{
"param1": "value1_2",
"param2": "value2_2"
}
]
}
var final_arr = {"result": 0,"items": []};
final_arr.items.push(r1.items);
final_arr.items.push(r2.items);
console.log(final_arr);

How to create a nested object from data using JavaScript?

Before
This is an object with multiple rows:
{
"functions": [
{
"package_id": "2",
"module_id": "2",
"data_id": "2"
},
{
"package_id": "1",
"module_id": "1",
"data_id": "2"
},
{
"package_id": "2",
"module_id": "3",
"data_id": "3"
}
]
}
Desired result
I want this to return into a "nested" Object like below, without duplicates:
{
"packages": [
{
"package_id": "2",
"modules": [
{
"module_id": "2",
"data": [
{
"data_id": "2"
}
]
},
{
"module_id": "3",
"data": [
{
"data_id": "3"
}
]
}
]
},{
"package_id": "1",
"modules": [
{
"module_id": "1",
"data": [
{
"data_id": "2"
}
]
}
]
}
]
}
I've already tried loops inside loops, with constructing multiple arrays and objects. Which causes duplicates or overriding objects into single ones. Is there a more generic way to generate this with JavaScript? (It's for an Angular (6) project.
Example 1
getFunctionPackage() {
var fList = this.functionList;
var dArr = [];
var dObj = {};
var pArr = [];
var pObj = {};
var mArr = [];
var mObj = {};
for (var key in fList) {
pObj['package_id'] = fList[key]['package_id'];
mObj['module_id'] = fList[key]['module_id'];
dObj['data_id'] = fList[key]['data_id'];
for (var i = 0; i < pArr.length; i++) {
if (pArr[i].package_id != pObj['package_id']) {
pArr.push(pObj);
}
for (var x = 0; x < mArr.length; x++) {
if (pArr[i]['modules'][x].module_id != mObj['module_id']) {
mArr.push(mObj);
}
for (var y = 0; y < dArr.length; y++) {
if (pArr[i]['modules'][x]['datas'][y].data_id != dObj['data_id']) {
dArr.push(dObj);
}
}
}
}
if (dArr.length == 0) {
dArr.push(dObj);
}
mObj['datas'] = dArr;
if (mArr.length == 0) {
mArr.push(mObj);
}
pObj['modules'] = mArr;
if (pArr.length == 0) {
pArr.push(pObj);
}
dObj = {};
mObj = {};
pObj = {};
}
}
Example 2:
Results in skipping cause of the booleans
var fList = this.functionList;
var dArr = [];
var dObj = {};
var pArr = [];
var pObj = {};
var mArr = [];
var mObj = {};
var rObj = {};
for (var key in fList) {
pObj['package_id'] = fList[key]['package_id'];
mObj['module_id'] = fList[key]['module_id'];
dObj['data_id'] = fList[key]['data_id'];
var pfound = false;
var mfound = false;
var dfound = false;
for (var i = 0; i < pArr.length; i++) {
if (pArr[i].package_id == pObj['package_id']) {
for (var x = 0; x < mArr.length; x++) {
if (pArr[i]['modules'][x].module_id == mObj['module_id']) {
for (var y = 0; y < dArr.length; y++) {
if (pArr[i]['modules'][x]['datas'][y].data_id == dObj['data_id']) {
dfound = true;
break;
}
}
mfound = true;
break;
}
}
pfound = true;
break;
}
}
if (!dfound) {
dArr.push(dObj);
mObj['datas'] = dArr;
dObj = {};
}
if (!mfound) {
mArr.push(mObj);
pObj['modules'] = mArr;
mObj = {};
}
if (!pfound) {
pArr.push(pObj);
pObj = {};
}
dArr = [];
mArr = [];
}
rObj['packages'] = pArr;
console.log(rObj);
Here's a more generic approach using Array#reduce() to create a grouped object based on the package id as keys. You can use any loop to build this same object ...for() or forEach() for example.
Then use Object.values() to get the final array from that grouped object
Using methods like Array#find() simplifies traversing to see if a module exists already or not within each package
const grouped = data.functions.reduce((a, c )=>{
// if group object doesn't exist - create it or use existing one
a[c.package_id] = a[c.package_id] || {package_id : c.package_id, modules: [] }
// store reference to the group modules array
const mods = a[c.package_id].modules
// look within that group modules array to see if module object exists
let module = mods.find(mod => mod.module_id === c.module_id)
if(!module){
// or create new module object
module = {module_id: c.module_id, data:[]}
// and push it into modules array
mods.push(module);
}
// push new data object to module data array
module.data.push({data_id: c.data_id})
return a
}, {})
// create final results object
const res = { packages : Object.values(grouped) }
console.log(res)
.as-console-wrapper {max-height: 100%!important;}
<script>
const data = {
"functions": [{
"package_id": "2",
"module_id": "2",
"data_id": "2"
},
{
"package_id": "1",
"module_id": "1",
"data_id": "2"
},
{
"package_id": "2",
"module_id": "3",
"data_id": "3"
}
]
}
</script>

How to get an JSON Object based in key using jquery

I'm using jsTree and have tree an structured JSON object.
[{
"id": 1,
"text": "TEXT_ONE",
"children": [
{
"id": 2,
"text": "TEXT_TWO",
"children": [
{
"id": 3,
"text": "TEXT_THREE",
"children": [
]
},
{
"id": 4,
"text": "TEXT_FOUR",
"children": [
]
}
]
},
{
"id": 5,
"text": "TEXT_FIVE",
"children": [
]
}
]
},
{
"id": 6,
"text": "TEXT_SIX",
"children": [ ]
}]
I want to get the the object based on the "id" of the object.
For example if i have a function getIdFromTree(3) it will return me the JSON object as following:
{
"id": 3,
"text": "TEXT_THREE",
"children": []
},
How I do that in Javascript/JQuery?
Try this
function getObjById (tree, id) {
if(tree.id === id) {
return tree;
}
if(tree.children) {
for(var i = 0, l = tree.children.length; i < l; i++) {
var returned = getObjById(tree.children[i], id);
if(returned) {
// so that the loop doesn't keep running even after you find the obj
return returned;
}
}
}
}
Call this as follows
getObjById({children: tree}, 3); // tree is the array object above.
function findById (tree, id) {
var result, i;
if (tree.id && tree.id === id) {
result = tree;
// Revalidate array list
} else if (tree.length) {
for (i = 0; i < tree.length; i++) {
result = findById(tree[i], id);
if (result) {
break;
}
}
// Check childrens
} else if (tree.children) {
result = findById(tree.children, id);
}
return result;
}
Use filter Methode off Array
data.filter(function (obj){ obj.id== 3});
try this.... Es6
function *getObjectById(data, id) {
if (!data) return;
for (let i = 0; i< data.length; i++){
let val = data[i];
if (val.id === id) yield val;
if (val.children) yield *getObjectById(val.children , id);
}
}
now
getObjectById(arrayOfObjects, id).next().value;
try this with most effective and efficient way..
function getObjById (tree, id) {
for(var i= 0;i<tree.length;i++)
{
if(tree[i].id===id)
{
return tree[i];
}
if(tree[i].children)
{
var returned = getObjById(tree[i].children,id);
if(returned!= undefined)
return returned;
}
}
};
link:
https://jsfiddle.net/aa7zyyof/14/

Ordering recursive function results in arrays of arrays

I am currently dealing with in issue in writing a recrusive function to order some json data. I have several nested arrays of objects which i need to order into single slides. The structure is similar to the following :
[
{
"title": "a",
"children": [
{
"title": "a-a",
"children": [
{
"title": "a-a-a"
},
{
"title": "a-a-b"
}
]
},
{
"title": "a-b",
"children": [
{
"title": "a-b-a"
},
{
"title": "a-b-b"
}
]
}
]
},
{
"title": "b",
"children": [
{
"title": "b-a",
"children": [
{
"title": "b-a-a"
},
{
"title": "b-a-b"
}
]
},
{
"title": "b-b",
"children": [
{
"title": "b-b-a"
},
{
"title": "b-b-b"
}
]
}
]
}
]
I have written a recursive function :
var catalog = {
init: function() {
var _this = this;
$.getJSON("catalog.json", function(data) {
_this.slides = [];
_this.parseCategories(data.catalog.category,-1,0);
});
},
parseCategories: function(array, depth, prevParent) {
++depth;
if (!this.slides[depth]) this.slides[depth] = [];
if (!this.slides[depth][prevParent]) this.slides[depth][prevParent] = [];
this.slides[depth][prevParent].push(array);
for (var i = 0; i < array.length; i++) {
if (array[i].category) {
this.parseCategories(array[i].category, depth, i);
}
}
}
}
catalog.init();
This outputs :
However instead of retrieving the data for my third slide under format :
a-a-a
a-b-a
a-c-a
I would like to get
a-a-[a,b,c]
I was wondering if that was possible since I'm not very good at handling recursive processes. I hope I was clear and thank you for reading this.
I basically need to keep my original data structure but remove the first depth level for each iteration (slide in a slider that represent increasing depths in my data structure).
I recently wrote a algorithm to recursively handle data like this. Here is a jsfiddle and the main function
console.log('starting');
// data in tree format.
var output = {};
// data in slide format ["a-a-a", "a-a-b", "b-b-a", "b-b-b"]
var outputStrs = [];
parseData(data, output);
console.log(output);
console.log(outputStrs);
function parseData(data, store) {
// go through each element
for (var i = 0; i < data.length; i++) {
var element = data[i];
// used to keep track of where we are in the tree.
var splitElement = element.title.split('-');
var titleStart = splitElement[0];
// console.log(element);
if (_.has(element, 'children') && _.isArray(element.children)) {
// if there is a children, then recursively handle it.
store[titleStart] = {};
parseData(element.children, store[titleStart]);
} else {
// if we are at the end, then add in the data differently.
var titleEnd = splitElement[splitElement.length-1];
store[titleEnd] = titleEnd;
// create the slides
var slide = [];
for (var j = 0; j < splitElement.length; j++) {
if (j !== splitElement.length - 1) {
slide.push(titleStart);
} else {
slide.push(titleEnd);
}
}
slide = slide.join('-');
if (!_.contains(outputStrs, slide)) outputStrs.push(slide);
}
}
}
With this data the output should resemble
a
a
a
b
b
b
a
b
And outputStrs will resemble a-a-[a,b,c]
Hope this helps!!!

Get the unique items - Handlebars

My JSON looks like this:
{
"features": [
{
"id": "belly",
"scenarios": [
{
"id": "belly;a-few-cukes",
"tags": [
{
"name": "#tag1"
}
],
"steps": [
{
"name": "I have 42 cukes in my belly"
},
{
"name": "I wait 1 hour"
},
{
"name": "my belly should growls"
}
]
},
{
"id": "belly;a-few-cukes-with-new-test",
"tags": [
{
"name": "#tag2"
}
],
"steps": [
{
"name": "I have 42 cukes in my belly"
},
{
"name": "I wait 1 hour"
},
{
"name": "my belly should growl"
}
]
}
]
},
{
"id": "newbelly",
"scenarios": [
{
"id": "newbelly;a-few-cukes-with-new-feature",
"tags": [
{
"name": "#tag1"
}
],
"steps": [
{
"name": "I have 42 cukes in my belly"
},
{
"name": "I wait 1 hour"
},
{
"name": "my belly should growls"
}
]
}
]
}
]
}
I would like to retrieve all the unique tag names: i.e., #tag1, #tag2. If you notice, the #tag1 is repeated twice.
My template:
{{#getTags features}}
{{#scenarios}}
{{#tags}}
<p>{{name}}</p>
{{/tags}}
{{/scenarios}}
{{/getTags}}
Custom Helper that I created so far:
Handlebars.registerHelper('getTags', function(context, block) {
var ret = "";
for (var i = 0; i < context.length; i++) {
ret += block.fn(context[i]);
};
return ret;
});
The above custom helper returns all the tags, but I want unique ones.
Something along these lines may work:
Handlebars.registerHelper('getTags', function(context, block) {
var ret = "";
var got = [];
function contains(obj, a) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
}
for (var i = 0; i < context.length; i++) {
if (!this.contains(context[i],got)) {
got.addObject(context[i]);
ret += block.fn(context[i]);
}
}
return ret;
});
Code used for testing, all javascript:
var ret = "";
var got = [];
var data = ["tag1", "tag1", "tag2", "tag3"]
function contains(obj, a) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
}
for (var i = 0; i < data.length; i++) {
if (!contains(data[i],got)) {
got.push(data[i]);
ret += data[i];
}
}
console.log( ret);

Categories