I have a json array this way,
var simple = [];
for (var i = 0; i < 5; i++) {
simple.push({ id: id, name: name, mobile: mobile });
}
And the values from this json array is as below,
[{id:1
name:"Test"
mobile:100},
{id:2
name:"Test"
mobile:200},
{id:3
name:"Temp"
mobile:300},
{id:4
name:"Test"
mobile:400},
{id:5
name:"Temp"
mobile:500}]
What i need to do is, I have to compare records in an json array based on "name" key.
While comparing, if record1.name = record2.name then i have to remove entire record1 and append "mobile" value of record1 with record2 , this way.
This is the final output expected.
[{id:1
name:"Test"
mobile:100,200,400},
{id:2
name:"Temp"
mobile:300,500}]
I tried removing this way. But not able to append the "mobile" key values with each other.
var removeItem = name;
alert('Array before removing the element = ' + simple);
simple = jQuery.grep(simple,
function(value) { return value != removeItem; });
alert('Array before removing the element = ' + simple);
Can some one help me in this?
Thanks
Edit
======
I tried Answer#1=given by Ismail Kuruca given below,
Its working fine with the existing keys I.E, If added new keys with the below input,
var input =
[{
id:1,
name:"Test",
ssn:1,
mobile:100,
address:"A"
},
{
id:2,
name:"Test1",
ssn:2,
mobile:200,
address:"B"
},
{
id:3,
name:"Temp",
ssn:3,
mobile:300,
address:"C"
},
{
id:4,
name:"Test2",
ssn:4,
mobile:400,
address:"D"
},
{
id:5,
name:"Temp1",
ssn:5,
mobile:500,
address:"E"
}];
Its is giving same value of "name" to all the newly added keys , as below,
here "ssn" should be equal to 1, but it is returning "name" value : "test"
[{"id":1,"name":"Test","ssn":"Test","mobile":"100"},{"id":2,"name":"Test1","ssn":"Test1","mobile":"200"},{"id":3,"name":"Temp","ssn":"Temp","mobile":"300"},{"id":4,"name":"Test2","ssn":"Test2","mobile":"400"},{"id":5,"name":"Temp1","ssn":"Temp1","mobile":"500"}]
I tried this way,
//This part transforms your input to a map for each "name" attribute
//Each key has a value of array of "mobile"
var intermediateObject = {};
for(var i = 0; i < input.length; i++) {
if(typeof intermediateObject[input[i].name] == 'undefined') {
intermediateObject[input[i].name] = [];
}
else if(typeof intermediateObject[input[i].ssn] == 'undefined') {
intermediateObject[input[i].ssn] = [];
}
intermediateObject[input[i].name].push(input[i].mobile);
intermediateObject[input[i].ssn].push(input[i].mobile);
}
//Here the intermediate transformation is re-adjusted to look like your
//intended output format
var outputObject = [];
var index = 1;
for(elem in intermediateObject ) {
outputObject.push({
id: index++,
name: elem,
ssn : elem,
mobile: intermediateObject[elem].join(",")
});
}
console.log(JSON.stringify(outputObject));
but it is not working.. Can some help me in this..
Output should be,
[{
id:1,
name:"Test",
ssn:1,
mobile:100,
address:"A"
},
{
id:2,
name:"Test1",
ssn:2,
mobile:200,
address:"B"
},
{
id:3,
name:"Temp",
ssn:3,
mobile:300,
address:"C"
},
{
id:4,
name:"Test2",
ssn:4,
mobile:400,
address:"D"
},
{
id:5,
name:"Temp1",
ssn:5,
mobile:500,
address:"E"
}];
Could you please help?
Here is a very crude example of transforming your input to desired output.
var input =
[{
id:1,
name:"Test",
ssn:1,
mobile:100,
address:"A"
},
{
id:2,
name:"Test",
ssn:1,
mobile:200,
address:"A"
},
{
id:3,
name:"Temp",
ssn:3,
mobile:300,
address:"C"
},
{
id:4,
name:"Test2",
ssn:4,
mobile:400,
address:"D"
},
{
id:5,
name:"Temp1",
ssn:5,
mobile:500,
address:"E"
}];
//This part transforms your input to a map for each "name" attribute
//Each key has a value of array of "mobile"
var intermediateObject = {};
for(var i = 0; i < input.length; i++) {
if(typeof intermediateObject[input[i].name] == 'undefined') {
intermediateObject[input[i].name] = { ssn: null, address: null, content:[]};
}
intermediateObject[input[i].name].content.push(input[i].mobile);
intermediateObject[input[i].name].ssn = input[i].ssn;
intermediateObject[input[i].name].address= input[i].address;
}
//Here the intermediate transformation is re-adjusted to look like your
//intended output format
var outputObject = [];
var index = 1;
for(elem in intermediateObject ) {
outputObject.push({
id: index++,
name: elem,
ssn: intermediateObject[elem].ssn,
address: intermediateObject[elem].address,
mobile: intermediateObject[elem].content.join(",")
});
}
EDIT: Modified the answer according to edit:
This is the output object:
[{"id":1,"name":"Test","ssn":1,"address":"A","mobile":"100,200"},{"id":2,"name":"Temp","ssn":3,"address":"C","mobile":"300"},{"id":3,"name":"Test2","ssn":4,"address":"D","mobile":"400"},{"id":4,"name":"Temp1","ssn":5,"address":"E","mobile":"500"}]
I used a temporary object to figure out if a key is repeated or not. I then applied reduce to store objects with non-repeated keys and update the mobile array that they have with the mobile of the repeated element.
function final(arr) {
var aux = {}, index = 0;
return arr.reduce(function (memo, el) {
var key = el.name,
obj = aux[key];
if (!obj) {
aux[key] = {
id: index++,
name: key,
mobile: el.mobile
};
memo = memo.concat(aux[key]);
} else {
obj.mobile += "," + el.mobile;
}
return memo;
}, []);
}
console.log(final(arr));
You can check the result in this fiddle.
Hope it helps.
Related
let student = [{
id:1,
name:'aman',
class:'10',
gender:'male'
},{
id:2,
name:'shivani',
class:'10',
gender:'female'
},{
id:2,
name:'riyan',
class:'11',
gender:'female'
}]
function customFilter(objList, text){
if(undefined === text || text === '' ) return objList;
return objList.filter(product => {
let flag;
for(let prop in product){
if(product[prop].toString().indexOf(text)>-1){
product[prop] = 0
product[prop]++
flag = product[prop]
console.log(flag)
}
}
return flag;
});}
console.log( customFilter(student, '10'))
I want the output of the number of students in a class. Example: when I pass class 10 as an argument then i should get output how many students in class 10
output:
{class:10,stduent:5 }
I didn't get your question well, but I assumed you want number of student in a class like this {class:10, students: 2}
let student = [
{ id:1, name:'aman', class:'10', gender:'male'},
{ id:2, name:'shivani', class:'10', gender:'female' },
{ id:3, name:'riyan', class:'11', gender:'female' }
]
function customFilter(objList, text){
if(undefined === text || text === '' ) return objList;
const numberOfStudents = objList.filter(product => {
for (let prop in product) {
if (product[prop].toString().includes(text)) {
return true;
}
}
});
return {class:text, student:numberOfStudents.length }
}
console.log( customFilter(student, '10'))
If that's the case this code will do , hope it helps
This would also work:
let students = [
{ id: 1, name: "aman", class: "10", gender: "male" },
{ id: 2, name: "shivani", class: "10", gender: "female" },
{ id: 2, name: "riyan", class: "11", gender: "female" },
];
const customFilter = (students, key, value) => {
const res = { [key]: value, student: 0 };
students.forEach((student) => {
if (student[key] === value) {
res.student += 1;
}
});
return res;
};
console.log(customFilter(students, "class", "10"));
Using Array.prototype.forEach()
There are few problems with the code. change class:'10' to grade: 10,.
don't use "class" as a variable name. might cause a few errors
There is a missing ,
numbers shouldn't be inside quotes because the number will be stored as a string
let student = [
{ id: 1, name: 'aman', grade: 10, gender: 'male'},
{ id: 2, name: 'shivani', grade: 10, gender: 'female' },
{ id: 2, name: 'riyan', grade: 11, gender: 'female' },
]
function customFilter(objList, value){
if(!value || value === '') return objList;
let count = 0
objList.forEach(obj => {
const { grade } = obj;
if(grade === value){
count++;
}
})
return {grade: 10, count};
}
console.log(customFilter(student, 10));
and forEach can be used instead of filter. It loops from start to end of an array
Use .reduce() to group all objects that match.
/* hits (accumulator) is initially an empty array.
now (current) is the object of the current iteration. */
array.reduce((hits, now) => { //...
On each iteration, get all of the current object's values (in lower case) in an array.
Object.values(now).map(val => val.toLowerCase())
/* result of the first object: ["01gn3z1ryjjqhn588ax3bws6qb", "theo bramstom",
"genderqueer", "english"] */
If any of the values of the current object matches the given string (term), add the current object to the hits array.
if (Object.values(now)
.map(val => val.toLowerCase()).includes(term.toLowerCase())) {
hits.push(now);
}
An object literal is returned.
{
"matches": /* an array of all matched objects */,
"total": /* the .length of "matches" array */
};
/* To get the answer prompted in OP -- do the following */
const x = dataFilter(students, "Math");
console.log(x.total);
// NOTE: key "class" is now "subject" just for aesthetics
const students=[{id:"01GN3Z1RYJJQHN588AX3BWS6QB",name:"Theo Bramstom",gender:"Genderqueer",subject:"English"},{id:"01GN3Z1RYM527HAX56ZN14F0YB",name:"Juli Marsy",gender:"Female",subject:"History"},{id:"01GN3Z1RYPYP1FFFEY55T92VX2",name:"Linc Espley",gender:"Non-binary",subject:"Math"},{id:"01GN3Z1RYR325M0QETVVPE2N5J",name:"Barbabas Grisley",gender:"Male",subject:"Math"},{id:"01GN3Z1RYTXA49SBQYXR9DMC04",name:"Godfree Braybrook",gender:"Male",subject:"English"},{id:"01GN3Z1RYVE4N5D16C8QWB1XGF",name:"Jason De Vuyst",gender:"Male",subject:"History"},{id:"01GN3Z1RYXY9WXF1Y407HXFYH8",name:"Adler McCanny",gender:"Male",subject:"Math"},{id:"01GN3Z1RYY9XV444J0SP5Y0QC2",name:"Noellyn MacMorland",gender:"Genderqueer",subject:"Math"},{id:"01GN3Z1RZ0HPQNZ1VKX8ZHA9ZY",name:"Padget Geldeford",gender:"Male",subject:"Math"},
{id:"01GN3Z1RZ2DZE92NG42KSGDXN9",name:"Milissent Treby",gender:"Female",subject:"Art"}];
const dataFilter = (array, term) => {
let result = array.reduce((hits, now) => {
if (Object.values(now).map(val => val.toLowerCase()).includes(term.toLowerCase())) {
hits.push(now);
}
return hits;
}, []);
return {"matches": result, "total": result.length};
}
console.log(dataFilter(students, "Math"));
// Control case: term === "Math"
console.log(dataFilter(students, "PE"));
// No match case: term != "PE"
console.log(dataFilter(students, "female"));
// Case insensitive case: term === "Female"
I have an array. If the name value is empty, I need to change it to the end of the array, how can I do that in Javascript?
ex:
const data : [
{
id:0,
name:"gorkem"
}
{
id:1,
name:""
}
{
id:2,
name:"ahmet"
}
];
Replace
const data : [
{
id:0,
name:"gorkem"
}
{
id:2,
name:"ahmet"
}
{
id:1,
name:""
}
];
Use two calls to filter, one to get the items with non-empty name, the other with the empty names. Then concatenate these two arrays.
let non_empty = data.filter(el => el.name);
let empty = data.filter(el => !el.name);
let result = non_empty.concat(empty);
You could just sort the array based on the "truthiness" of the "name".
const data = [{
id:0,
name:"gorkem"
}, {
id:1,
name:""
}, {
id:2,
name:"ahmet"
}];
console.log(data.sort((a,b)=>!a.name - !b.name));
Above, we are basically abusing the fact that an empty string is a falsy value which is equivalent to 0, while a non empty string is truthy, which is equivalent to 1. Each are negated with a "!" to get the reversed sort order you are after and to actually treat them as booleans.
result :
[
{
"id": 0,
"name": "gorkem"
},
{
"id": 2,
"name": "ahmet"
},
{
"id": 1,
"name": ""
}
]
First of all you need to have a valid array:
const data = [{
id:0,
name:"gorkem"
}, {
id:1,
name:""
}, {
id:2,
name:"ahmet"
}];
So, starting with that you can use a loop to remove empty name element and add to the end:
for (let i = 0; i < data.length; i++) {
if (data[i].name === '') {
let val = data[i];
data.splice(i, 1);
data.push(val);
}
}
I'm having an array of object,in which I'm storing the billkey and billvalue as attributes. I want billkey to be the key and billvalue to be the value of that particular key.
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
}
{
billkey:"Name",
billvalue:"XYZ"
},
{
billkey:"Department",
billvalue:"Electrical"
}];
And I want to convert it into this format:
var log=[
{
Name:"ABC",
Department:"Computer"
},
{
Name:"XYZ",
Department:"Electrical"
}];
How about this simple solution. Hope it helps!
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
},
{
billkey:"Name",
billvalue:"XYZ"
},
{
billkey:"Department",
billvalue:"Electrical"
}];
var arr = [];
var finalObj = [];
for(var i in log){
var someObject = log[i];
for(var j in someObject){
arr.push(someObject[j]);
}
}
for(var k = 0; k < arr.length; k+=4){
finalObj.push({
Name: arr[k+1],
Department: arr[k+3]
});
}
console.log(finalObj);
create the result using forloop
// store the values
var logs=[];
var log=[
{
billkey:"Name",
billvalue:"ABC"
},
{
billkey:"Department",
billvalue:"Computer"
},
{
billkey:"Name",
billvalue:"XYZ"
},
{
billkey:"Department",
billvalue:"Electrical"
},
];
loop the first array
for (i = 0; i < log.length; i++) {
// create empty variable for storing the values
var index = new Array();
// insert the first index value to key
index[log[i].billkey] = log[i].billvalue
// insert the second index value to key
index[log[i+1].billkey] = log[i+1].billvalue
// insert the result in to new array
logs.push(index);
// increment the i with 1
i=i+1;
}
console.log(logs);
You could use Array#reduce and use the remainder operator as witch for using either the last object or create a new one.
var log = [{ billkey: "Name", billvalue: "ABC" }, { billkey: "Department", billvalue: "Computer" }, { billkey: "Name", billvalue: "XYZ" }, { billkey: "Department", billvalue: "Electrical" }],
result = log.reduce(function (r, a, i) {
var o = {};
if (i % 2) {
r[r.length - 1][a.billkey] = a.billvalue;
} else {
o[a.billkey] = a.billvalue;
r.push(o);
};
return r;
}, []);
console.log(result);
Say i have a collection of objects like so
var collection = [
{
name:"John",
age:12,
location:"Califonia",
gender:"Male"
},
{
name:"Jane",
age:18,
location:"New york",
gender:"Female"
}
]
it is obvious "location" is the object key with the longest character length.
But how can i get this dynamically as i dont know how collection will be structured in advance.
With these functions:
/**
* Get the longest key in an object.
*/
function longestKey(obj) {
return Object.keys(obj).reduce(function(all, current) {
return all.length > current.length ? all : current;
});
}
/**
* Get the object with the longest key from array of objects.
*/
function longestKeyObj(arr) {
return arr.reduce(function(all, current) {
return longestKey(all).length > longestKey(current).length ? all : current;
});
}
You can do:
const me = {
name: 'nabil',
occupation: 'programming',
dob: '1984-12-28',
};
const you = {
longestKey: 'blah!',
};
console.log('The object is: ', longestKeyObj([me, you]));
console.log('The key is: ', longestKey(longestKeyObj([me, you])));
Which outputs:
The object is: { longestKey: 'blah!' }
The key is: longestKey
Demo: https://repl.it/#kadimi/longestKey
if you are sure the items in the collection will always have the same structure you can simple do this.
var collection = [
{
name:"John",
age:12,
location:"Califonia",
gender:"Male"
},
{
name:"Jane",
age:18,
location:"New york",
gender:"Female"
}
]
function getMaxKeys(collection){
var keys = Object.keys(collection[0]);
var keyWithMaxWidth = keys.reduce(function(prev, current){
if(prev.length > current.length) return prev;
else return current
});
return keyWithMaxWidth;
}
getMaxKeys(collection) //location
you can get array object key of specific object by command :
Object.keys(<object>)
Make a loop for find longest key. In your problem you need loop for all object in array
The code below will solve your problem in optimal way:
var sorted = (Object.keys(collection[0])).sort(function(a, b){
return b.length - a.length;
});
sorted[0]; // Location
You can loop each object in the array and then loop each property in the object like so:
var collection = [
{
name:"John",
age:12,
location:"Califonia",
gender:"Male"
},
{
name:"Jane",
age:18,
location:"New york",
gender:"Female"
},
{
veryLong: "This key will definitely be the longest"
}
];
var stats = {
key: '',
valLen: 0
};
collection.forEach(function(obj){
for(var prop in obj){
if(obj[prop].length > stats.valLen){
stats.key = prop
stats.valLen = obj[prop].length
}
}
});
console.log(stats.key);
console.log(stats.valLen);
Each item in the array may have a different format.
This example will log: 'veryLong' as longest key and 39 as its length.
See this fiddle
Just loop through the keys with Object.keys(obj) and pick up the longest one, Use the following function:
var getLongestKey = function getLongestKey(obj) {
for (key in keys) {
if (keys[key].length > longest.length) {
longest = keys[key];
}
}
}
And this is a working demo, to get the longest key for all the objects in the array :
var collection = [{
name: "John",
age: 12,
location: "Califonia",
gender: "Male"
}, {
name: "Jane",
age: 18,
location: "New york",
gender: "Female"
}];
var getLongestKey = function getLongestKey(obj) {
for (key in keys) {
if (keys[key].length > longest.length) {
longest = keys[key];
}
}
}
for (i = 0; i < collection.length; i++) {
var obj = collection[i];
var keys = Object.keys(obj);
var longest = keys[0];
getLongestKey(obj);
alert("Longest key in Object " + i + " is : " + longest);
}
I need to make an extension to existing code, can't change it.
There's this array:
var availableTags = [
{ label: "Yoga classes", category: "EDUCATIONAL" },
{ label: "Cooking classes", category: "EDUCATIONAL" },
{ label: "Cheese tastings", category: "EDUCATIONAL" },
{ label: "Maker Workshops", category: "PRACTICAL" },
{ label: "Seminars", category: "PRACTICAL" },
//many more of these
];
Now I need to check if a text entered in an input box is included in one of the labels, e.g. if the user enters "Yoga classes" => OK, if "Yoga" => NOK, "sdsdf" => NOK, etc.
What is the best way to do this? I am not sure I can use Array.indexOf as I am not sure how to pass the Object to the function, I would try looping through the array (around 40 entries) and compare each object.
You need to loop over every item in availableTags and check whether that item's label is equal to some input. Try something like this:
var input = "Yoga classes";
var found = false;
for (var i = 0, j = availableTags.length; i < j; i++) {
var cur = availableTags[i];
if (cur.label === input) {
found = true;
break;
}
}
console.log(found);
DEMO: http://jsfiddle.net/k4cp4/4/
Where this can easily be put into a function, like:
var checkMatch = (function () {
var availableTags = [
{ label: "Yoga classes", category: "EDUCATIONAL" },
{ label: "Cooking classes", category: "EDUCATIONAL" },
{ label: "Cheese tastings", category: "EDUCATIONAL" },
{ label: "Maker Workshops", category: "PRACTICAL" },
{ label: "Seminars", category: "PRACTICAL" }
];
return function (input) {
var found = false;
for (var i = 0, j = availableTags.length; i < j; i++) {
var cur = availableTags[i];
if (cur.label === input) {
found = true;
break;
}
}
return found;
};
})();
DEMO: http://jsfiddle.net/k4cp4/5/
This checks for an exact match. So if you want a case insensitive match, you can use:
if (cur.label.toLowerCase() === input.toLowerCase()) {
DEMO: http://jsfiddle.net/k4cp4/6/
If you want to see if any of the labels contain the input, you can use indexOf like:
if (cur.label.indexOf(input) > -1) {
DEMO: http://jsfiddle.net/k4cp4/7/
You can use Array.some method:
Tests whether some element in the array passes the test implemented by the provided function.
Then your code would look something like:
var isFound = availableTags.some(function(el) {
return el.label === 'Yoga classes';
});
Note: some method needs to be shimmed.
var check = function(item) {
for(at in availableTags) {
if(item == availableTags[at].label) {
return true;
}
}
return false;
}
console.log(check("Yoga classes"));