Insert element inside another element in the same array - javascript

I've been looking for a solution for this with no luck.
I have an JSON object:
arr = [
{
"id": "1",
"dataId" : "",
"rel": ""
},
{
"id": "2",
"dataId" : "",
"rel": ""
},
{
"id": "3",
"dataId" : "",
"rel": ""
},
{
"id": "4",
"dataId" : "1",
"rel": ""
}];
I need a way to manipulate this array with javascript (jquery is allowed), so when "arr[a].dataId" match with the "arr[b].id", take "arr[a]" element and insert into "arr[b]" creating a new array like this:
newArr = [
{
"id": "1",
"dataId" : "",
"rel" : [
{
"id": "4",
"dataId" : "1"
}
]
},
{
"id": "2",
"dataId" : "",
"rel": ""
},
{
"id": "3",
"dataId" : "",
"rel": ""
}
];
I hope you understand what I'm asking, any help will be appreciated.
Thanks in advance

This one does move the elements and doesn't manipulate the array while it's iterating over it. Also doesn't need to extend the Array.prototype. One downside is that you're going to get holes in your array (indexes of elements won't be 0 to length-1), but from what I can see it's not important in your use case.
var arr = [
{
"id": "1",
"dataId" : "",
"rel": ""
},
{
"id": "2",
"dataId" : "3",
"rel": ""
},
{
"id": "3",
"dataId" : "",
"rel": ""
},
{
"id": "4",
"dataId" : "1",
"rel": ""
}];
var indexesToMoveMap = {};
$.each(arr, function(outerIndex, outerElem) {
if (outerElem.dataId) {
$.each(arr, function(innerIndex, innerElem) {
if (innerElem.id === outerElem.dataId) {
indexesToMoveMap[outerIndex] = innerIndex;
}
});
}
});
$.each(indexesToMoveMap, function(indexToMove, indexToMoveTo) {
arr[indexToMoveTo].rel = arr[indexToMoveTo].rel || [];
arr[indexToMoveTo].rel.push(arr[indexToMove]);
delete arr[indexToMove];
});
console.log(arr);

Try this:
var arr = [
{
"id": "1",
"dataId" : "",
"rel": ""
},
{
"id": "2",
"dataId" : "",
"rel": ""
},
{
"id": "3",
"dataId" : "",
"rel": ""
},
{
"id": "4",
"dataId" : "1",
"rel": ""
}];
$(arr).each(function(index,value){
if(value.dataId)
{
$(arr).each(function(ind,val){
if(val.id==value.dataId)
{
if(val.rel)
{
val.rel.push({"id":value.id,"dataId":value.dataId});
}
else
{
val.rel=[{"id":value.id,"dataId":value.dataId}];
}
}
});
}
});
console.log(arr);
Fiddle http://jsfiddle.net/7g23B/

Something like this?
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
var arr = [
{
"id": "1",
"dataId" : "",
"rel": []
},
{
"id": "2",
"dataId" : "",
"rel": []
},
{
"id": "3",
"dataId" : "",
"rel": []
},
{
"id": "4",
"dataId" : "1",
"rel": []
}];
var index = 0;
for ( var m = 0; m < arr.length; m++ ) {
for ( var i = 0; i < arr.length; i++ ) {
if ( arr[index].id === arr[i].dataId ) {
arr[index].rel.push (arr[i]);
arr.remove(i);
}
}
index++;
}
console.log(JSON.stringify(arr, null, 4))

Related

Filter Array based on the Filtering of Another Object having Multiple array in javascript

I have an array of objects. i want to filter array based the object has the condition.
my array is as follow :
var data = [
{
"name": "nitin",
"r_id": "1",
"t_id": "4"
},
{
"name": "test",
"r_id": "2",
"t_id": "3"
},
{
"name": "test1",
"r_id": "2",
"t_id": "4"
},
{
"name": "test3",
"r_id": "3",
"t_id": "3"
},
{
"name": "test2",
"r_id": "1",
"t_id": "1"
}]
and my object is as follows :
var obj = {
role:['1','2'],
type:['1','3']
}
where r_id is the role id and t_id is the type id
so i want the results whose role id is in 1 or 2 AND type id is in 1 or 3.
so mathematically role_id && type_id ((1||2)&&(1||3))
my output should like:
var result = [
{
'name':'test',
'r_id':2,
't_id':3,
},
{
'name':'test2',
'r_id':1,
't_id':1,
}];
var data = [
{
"name": "nitin",
"r_id": "1",
"t_id": "4"
},
{
"name": "test",
"r_id": "2",
"t_id": "3"
},
{
"name": "test1",
"r_id": "2",
"t_id": "4"
},
{
"name": "test3",
"r_id": "3",
"t_id": "3"
},
{
"name": "test2",
"r_id": "1",
"t_id": "1"
}]
var obj = {
role:['1','2'],
type:['1','3']
}
let result = data.filter(item=>{
return obj.role.indexOf(item.r_id) > -1 && obj.type.indexOf(item.t_id) > -1
})
console.log(result)
var data = [
{
"name": "nitin",
"r_id": "1",
"t_id": "4"
},
{
"name": "test",
"r_id": "2",
"t_id": "3"
},
{
"name": "test1",
"r_id": "2",
"t_id": "4"
},
{
"name": "test3",
"r_id": "3",
"t_id": "3"
},
{
"name": "test2",
"r_id": "1",
"t_id": "1"
}]
var obj = {
role:['1','2'],
type:['1','3']
}
var filterItems = data.filter(function(o){
return obj.role.indexOf(o.r_id) != -1 && obj.type.indexOf(o.t_id) != -1; });
console.log(filterItems);
You could change obj a bit, for corresponding property names in the data, you have, then use Array#filter and check with Array#every for wanted item.
var data = [{ name: "nitin", r_id: "1", t_id: "4" }, { name: "test", r_id: "2", t_id: "3" }, { name: "test1", r_id: "2", t_id: "4" }, { name: "test3", r_id: "3", t_id: "3" }, { name: "test2", r_id: "1", t_id: "1" }],
obj = { r_id: ['1', '2'], t_id: ['1', '3'] },
keys = Object.keys(obj),
result = data.filter(function (o) {
return keys.every(function (k) {
return obj[k].indexOf(o[k]) !== -1;
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You just need to iterate your data and see if the keys (r_id and t_id) are present in the obj (in the respective arrays). For this you can use Array.filter
var data = [{"name":"nitin","r_id":"1","t_id":"4"},{"name":"test","r_id":"2","t_id":"3"},{"name":"test1","r_id":"2","t_id":"4"},{"name":"test3","r_id":"3","t_id":"3"},{"name":"test2","r_id":"1","t_id":"1"}]
var obj = {
role:['1','2'],
type:['1','3']
}
var result = data.filter(function(element){
return obj.role.indexOf(element.r_id) !== -1 && // element has valid role
obj.type.indexOf(element.t_id) !== -1 // element has valid type
})
console.log(result)

Merging two json array object based on union and intersection

I am trying to merge two json array with objects as element. You may refer to this plunkr file for both json. I have succesfully retrieve the expected final outcome array id, but I do not know how to form back the expected json as below. I am using underscore js for this purpose.
Note: If object exist in newJson and not in currentJson, after merge, it will be inactive state by default.
I am not sure whether I am using the correct approach. This is what I have try:
var newJsonID = _.pluck(newJson, 'id');
var currentJsonID = _.pluck(currentJson, 'id');
var union = _.union(newJsonID, currentJsonID);
var intersection = _.intersection(currentJsonID, newJsonID);
var final = _.difference(union, _.difference( currentJsonID, intersection);
Expected Final Outcome:
[
{
"id": "12",
"property1Name": "1"
"status": "inactive"
},
{
"id": "11",
"property1Name": "1"
"status": "inactive"
},
{
"id": "10",
"property1Name": "1"
"status": "inactive"
},
{
"id": "9",
"property1Name": "1"
"status": "active"
}
]
A solution in plain Javascript with two loops and a hash table for lookup.
function update(newArray, currentArray) {
var hash = Object.create(null);
currentArray.forEach(function (a) {
hash[a.id] = a.status;
});
newArray.forEach(function (a) {
a.status = hash[a.id] || 'inactive';
});
}
var newJson = [{ "id": "12", "property1Name": "1" }, { "id": "11", "property1Name": "1" }, { "id": "10", "property1Name": "1" }, { "id": "9", "property1Name": "1" }],
currentJson = [{ "id": "10", "property1Name": "1", "status": "inactive" }, { "id": "9", "property1Name": "1", "status": "active" }, { "id": "8", "property1Name": "1", "status": "active" }, { "id": "7", "property1Name": "1", "status": "inactive" }];
update(newJson, currentJson);
document.write('<pre>' + JSON.stringify(newJson, 0, 4) + '</pre>');

Sorting arrays and indexes

I have a problem with sorting a fixed data table. I tried to use this example:
https://github.com/facebook/fixed-data-table/blob/master/examples/old/SortExample.js
When I first sort by name descending, it sorts successfully and brings to the first two lines to these values:
id:11 name:Mary
id:1 name:Mary
....
After that I sorted by name ascending, and then again I sorted by name descending once again.
It brings first two columns these values:
id:1 name:Mary
id:11 name:Mary
....
Why does it change the indexes of the same name values? (id:11 and id:1)
I need the same sort indexes every time. What is the problem and how can I solve it?
var SortTypes = {
ASC: 'ASC',
DESC: 'DESC',
};
function renderDate(/*object*/ cellData) {
return <span>{cellData.toLocaleString()}</span>;
}
var SortExample = React.createClass({
getInitialState() {
return {
rows: [{"id":"1","name":"Mary"},{"id":"2","name":"Felix"},
{"id":"3","name":"Mary"},{"id":"4","name":"Felix"},
{"id":"5","name":"Mary"},{"id":"6","name":"Felix"},
{"id":"7","name":"Mary"},{"id":"8","name":"Felix"},
{"id":"9","name":"Mary"},{"id":"10","name":"Felix"},
{"id":"11","name":"Mary"},{"id":"12","name":"Felix"},
{"id":"13","name":"Mary"},{"id":"14","name":"Felix"},
{"id":"15","name":"Mary"},{"id":"16","name":"Felix"},
{"id":"17","name":"Mary"},{"id":"18","name":"Felix"} ,
{"id":"19","name":"Mary"},{"id":"20","name":"Felix"}],sortBy: 'id',
sortDir: null,
};
},
_rowGetter(rowIndex) {
return this.state.rows[rowIndex];
},
_sortRowsBy(cellDataKey) {
var sortDir = this.state.sortDir;
var sortBy = cellDataKey;
if (sortBy === this.state.sortBy) {
sortDir = this.state.sortDir === SortTypes.ASC ? SortTypes.DESC : SortTypes.ASC;
} else {
sortDir = SortTypes.DESC;
}
var rows = this.state.rows.slice();
rows.sort((a, b) => {
var sortVal = 0;
if (a[sortBy] > b[sortBy]) {
sortVal = 1;
}
if (a[sortBy] < b[sortBy]) {
sortVal = -1;
}
if (sortDir === SortTypes.DESC) {
sortVal = sortVal * -1;
}
return sortVal;
});
this.setState({
rows,
sortBy,
sortDir,
});
},
_renderHeader(label, cellDataKey) {
return (
<a onClick={this._sortRowsBy.bind(null, cellDataKey)}>{label}</a>
);
},
render() {
var sortDirArrow = '';
if (this.state.sortDir !== null){
sortDirArrow = this.state.sortDir === SortTypes.DESC ? ' ↓' : ' ↑';
}
return (
<Table
rowHeight={50}
rowGetter={this._rowGetter}
rowsCount={this.state.rows.length}
headerHeight={50}
width={1000}
height={500}
{...this.props}>
<Column
headerRenderer={this._renderHeader}
label={'id' + (this.state.sortBy === 'id' ? sortDirArrow : '')}
width={100}
dataKey='id'
/>
<Column
headerRenderer={this._renderHeader}
label={'First Name' + (this.state.sortBy === 'name' ? sortDirArrow : '')}
width={200}
dataKey='name'
/>
</Table>
);
},
});
ReactDOM.render(
<SortExample/>,
document.getElementById('app')
)
For a stable sort, you need some more sort parameter like this solution which sorts first by name and then by id.
var rows = [{ "id": "1", "name": "Mary" }, { "id": "2", "name": "Felix" }, { "id": "3", "name": "Mary" }, { "id": "4", "name": "Felix" }, { "id": "5", "name": "Mary" }, { "id": "6", "name": "Felix" }, { "id": "7", "name": "Mary" }, { "id": "8", "name": "Felix" }, { "id": "9", "name": "Mary" }, { "id": "10", "name": "Felix" }, { "id": "11", "name": "Mary" }, { "id": "12", "name": "Felix" }, { "id": "13", "name": "Mary" }, { "id": "14", "name": "Felix" }, { "id": "15", "name": "Mary" }, { "id": "16", "name": "Felix" }, { "id": "17", "name": "Mary" }, { "id": "18", "name": "Felix" }, { "id": "19", "name": "Mary" }, { "id": "20", "name": "Felix" }];
rows.sort(function (a, b) {
return a.name.localeCompare(b.name) || a.id - b.id;
});
document.write('<pre>' + JSON.stringify(rows, 0, 4) + '</pre>');

How to Sort the JSON array in the controller of AngularJS?

Kindly help me in sorting the below JSON list in the controller and display in the view.
Actually orderBy filter sorting one level, But I need it sort even for childs recursively.
Input:
R2
-->S4
------>T5
------>T4
-->S3
R1
-->S2
------>T2
------>T1
-->S1
Output:
R1
-->S1
------>T1
------>T2
-->S2
R2
-->S3
------>T4
------>T5
-->S4
Please find the sample in Plunker.
http://plnkr.co/edit/JslHwJ1CBREKf6FgYHaZ?p=preview
var sortNames = function(arr){
arr = arr.sort(function(a,b){
return a.name > b.name;
})
for (var i = 0; i < arr.length; i++){
if (arr[i].childs){
sortNames(arr[i].childs)
}
}
return arr;
}
var names = [
{
"name": "Root1",
"Id": "2f3d17cb-d9e2-4e99-882d-546767f2765d",
"status": "",
"dispName": "",
"imageURL": "",
"childCount": "",
"childs": [
{
"name": "Sub1",
"Id": "ff8b3896-3b80-4e1b-be89-52a82ec9f98f",
"childs": [
{
"name": "Template1",
"Id": "ff8b3896-3b80-4e1b-be89-52a82ec9f981",
"status": "",
"dispName": "",
"imageURL": ""
},
{
"name": "Template2",
"Id": "ff8b3896-3b80-4e1b-be89-52a82ec9f982",
"status": "",
"dispName": "",
"imageURL": ""
}
]
},
{
"name": "Template3",
"Id": "ff8b3896-3b80-4e1b-be89-52a82ec9f981"
}
]
},
{
"name": "Root2",
"Id": "ea0586e7-02cf-4359-94ba-8d9623590dfe",
"childs": [
{
"name": "Sub2",
"Id": "6f1b3a60-d295-413e-92ef-1c713446e6c9",
"childs": [
{
"name": "Template4",
"Id": "6f1b3a60-d295-413e-92ef-1c713446e6c1"
},
{
"name": "Template5",
"Id": "6f1b3a60-d295-413e-92ef-1c713446e6c2"
}
]
}
]
}
];
sortNames(names);

How to select json item from the array

From the below JSON, how can I retrieve title from the note and notes using a for loop and ajax to retrieve?
{
"infos": {
"info": [
{
"startYear": "1900",
"endYear": "1930",
"timeZoneDesc": "daweerrewereopreproewropewredfkfdufssfsfsfsfrerewrBlahhhhh..",
"timeZoneID": "1",
"note": {
"notes": [
{
"id": "1",
"title": "Mmm"
},
{
"id": "2",
"title": "Wmm"
},
{
"id": "3",
"title": "Smm"
}
]
},
"links": [
{ "id": "1", "title": "Red House", "url": "http://infopedia.nl.sg/articles/SIP_611_2004-12-24.html" },
{ "id": "2", "title": "Joo Chiat", "url": "http://www.the-inncrowd.com/joochiat.htm" },
{ "id": "3", "title": "Bake", "url": "https://thelongnwindingroad.wordpress.com/tag/red-house-bakery" }
]
}
I tried out the code below but it doesn't work - it either says:
is null
not an object
length is null
r not an object
var detail = eval(xmlhttprequest.responseText)
var rss = detail.infos.info
for(var i = 0; i<rss.length; i++)
startyear += rss[i].startyear
Use
for (i = 0; i < 3; i++) {
alert(JSON.infos.info[0].note.notes[i].title);
}
TRY IT HERE: JSFIDDLE WORKING EXAMPLE
BTW your JSON is not valid. Use this JSON:
var JSON = {
"infos": {
"info": [
{
"startYear": "1900",
"endYear": "1930",
"timeZoneDesc": "daweerrewereopreproewropewredfkfdufssfsfsfsfrerewrBlahhhhh..",
"timeZoneID": "1",
"note": {
"notes": [
{
"id": "1",
"title": "Mmm"
},
{
"id": "2",
"title": "Wmm"
},
{
"id": "3",
"title": "Smm"
}
]
},
"links": [
{
"id": "1",
"title": "Red House",
"url": "http://infopedia.nl.sg/articles/SIP_611_2004-12-24.html"
},
{
"id": "2",
"title": "Joo Chiat",
"url": "http://www.the-inncrowd.com/joochiat.htm"
},
{
"id": "3",
"title": "Bake",
"url": "https://thelongnwindingroad.wordpress.com/tag/red-house-bakery"
}
]
}
]
}
}
EDIT:
Here is what you want:
var infoLength= JSON.infos.info.length;
for (infoIndex = 0; infoIndex < infoLength; infoIndex++) {
var notesLength= JSON.infos.info[infoIndex].note.notes.length;
for (noteIndex = 0; noteIndex < notesLength; noteIndex++) {
alert(JSON.infos.info[infoIndex].note.notes[noteIndex].title);
}
}
Putting your json into an var called obj, use the following:
obj.infos.info[0].note.notes[0].title
http://jsfiddle.net/Znq34/
Well the "path" to the JSON notes array-like object is:
json.infos.info[0].note.notes;
So you could do something like:
var notes = json.infos.info[0].note.notes;
var titles = [];
for (var i = 0, len = notes.length; i < len; i++)
{
titles.push(notes[i].title);
}
alert('titles is: ' + titles.join(', '));
Fiddle: http://jsfiddle.net/garreh/uDxqD/
Are you using jQuery? ;-)
// Assuming your using "success" in ajax response
success: function(json)
{
var titles = $(json.infos.info[0].note.notes).map(function() {
return this.title;
}).get();
alert(titles.join(', '));
}
First count the length of notes
var len = jsonobject.infos.info.note.notes.length;
Then loops through and get
var title = jsonobject.infos.info.note.notes[i].title;

Categories