let data = [{
name: "John"
school: ["def","abc"]
},
{
name: "Lily"
school: "xyz"
}, {
name: "Rose"
school: "abc"
}]
I wanna return object which has school=="abc"`. i had try array.includes("abc). but it doesnt give expected output. it only return object which school that have only "abc" (output: Rose-abc). John should be included too
You could use
Array#filter for getting a new array with only some items of the array,
destructuring (assignment) for getting only a single property of an object,
a comparison with the wanted value, by checking if school is an array and if not make an array and take Array#includes for the check.
This is the return value of the arrow function.
var array = [{ name: "John", school: ["def", "abc"] }, { name: "Lily", school: "xyz" }, { name: "Rose", school: "abc" }],
result = array.filter(({ school }) => (Array.isArray(school) ? school : [school]).includes('abc'))
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
arr = [{
name: "John",
school: "abc"
}, {
name: "Lily",
school: "xyz"
}, {
name: "Rose",
school: "abc"
}]
a = arr.filter((x) => {
if (x.school == 'abc')
return x
})
console.log(a)
JSFiddle
var arr = [];
arr.push({ name: "John", school:"abc" });
arr.push({ name: "Lily", school:"xyz" });
arr.push({ name: "Rose", school:"abc" });
var temp = [];
arr.forEach(function(el) {
if(el.school == "abc")
temp.push(el);
});
console.log(temp);
arr1 = [];
var arr1= array1.concat(arr2);
var index = arr1.findIndex(x => x.school== "abc");
if ( index != -1 ){
console.log(" found")
}
first of all concat the array of two arrays and store arr1
then find index of the arr1 which of that value abc if that value is not found
it will return -1 based on this you can value is present or not
Say your array is like,
var arr=[ { name: "John" school:"abc" },
{ name: "Lily" school:"xyz" },
{ name: "Rose" school:"abc" }
]
then you can get the object like,
var item = arr.filter((obj)=>obj.school==="abc");
now, item will have the object you need
#mr ukta, if I'm understood correctly, it might help you.
var students = [
{
name: "John",
school:["abc", "def"]
},
{
name: "John2",
school:"Boom"
},
{
name: "John3",
school:"abc"
},
];
var abcStudents = students.filter(({ school }) => (Array.isArray(school) ? school : [school]).includes('abc'))
console.log(abcStudents);
Related
I want to duplicate entire objects inside an array, based on the properties inside the object. I need to duplicate the objects, based on the split emails, in nominations.
For example
array = [
{
id:1,
name: ravi,
nominations: xyz#gmail.com, abc#gmail.com
},
{
id:2
name: ramu,
nominations: 123#gmail.com, 456#gmail.com
}
]
Need Output like
Output_array = [
{
id:1,
name: ravi,
nominations: xyz#gmail.com
},
{
id:1,
name: ravi,
nominations: abc#gmail.com
},
{
id:2
name: ramu,
nominations: 123#gmail.com
},
{
id:2
name: ramu,
nominations: 456#gmail.com
}
]
The easiest way would be to flatMap over the items, then map over the nominations.
const data = [{
id:1,
name: "ravi",
nominations: "xyz#gmail.com, abc#gmail.com"
},
{
id:2,
name: "ramu",
nominations: "123#gmail.com, 456#gmail.com"
}];
const result = data.flatMap(item => {
return item.nominations.split(", ").map(email => ({
id: item.id,
name: item.name,
nomination: email
}))
})
console.log(result)
A pretty straightforward way using loops:
let data = [
{
"id": 1,
"name": "ravi",
"nominations": "xyz#gmail.com,abc#gmail.com"
},
{
"id": 2,
"name": "ramu",
"nominations": "123#gmail.com,456#gmail.com"
}
];
let newData = []
for (let element of data) {
let emailIds = element.nominations.split(",");
if (emailIds.length > 1) {
for (let emailId of emailIds)
newData.push({ id: element.id, name: element.name, nominations: emailId })
}
}
console.log(newData)
Explanation: Starting with traversing the entire objects, in each object you split the nominations string and split it with "," to check if there is more than one email. If it does exist, you run a loop to individually add them.
This could be done with an arguably long one-liner. Object.assign function can be employed to duplicate input object while changing property/properties of interest.
let input = [{
id: 1,
name: `ravi`,
nominations: `xyz#gmail.com, abc#gmail.com`
},
{
id: 2,
name: `ramu`,
nominations: `123#gmail.com, 456#gmail.com`
}];
let output = input.flatMap(i => i.nominations.split(",").map(n => Object.assign({}, i, { nominations: n.trim() })));
console.log(output);
You can try this code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var data_array = [
{
id:'1',
name: 'ravi',
nominations: 'xyz#gmail.com, abc#gmail.com',
},
{
id:'2',
name: 'ramu',
nominations: '123#gmail.com, 456#gmail.com',
},
];
var output_array = data_array.flatMap(key => {
return key.nominations.split(",").map(split_email => ({
id: key.id,
name: key.name,
nomination: $.trim(split_email)
}))
});
console.log(output_array);
});
</script>
</head>
<body>
</body>
</html>
I have the following object:
[
{ name: "Peter", id: 25, job: "carpenter" },
{ name: "Peter", id: 25, job: "shelf maker" },
{ name: "John", no: 20, job: "student" },
{ name: "John", id: 20, job: "university student" },
{ name: "John", id: 20, job: "student at uni still" },
{ name: "Jack", id: 20, job: "university student" }
]
I would like to go through this array and whenever name and id are identical I would like to only keep one entry, namely the one appearing the latest in the array, and discard all the rest. How would I do this?
I have tried
for(let i=0;i<people.length;i++) {
const person = people[i];
const result = people.filter(person => person.id === id && person.name === name);
people[i] = person;
}
... but this doesn't work. Any ideas what I'm doing wrong? How would you approach this?
You could use reduceRight to build new array starting the iteration from the end of the array, and also Map as accumulator value to store key - value pairs.
const data = [{"name":"Peter","id":25,"job":"carpenter"},{"name":"Peter","id":25,"job":"shelf maker"},{"name":"John","no":20,"job":"student"},{"name":"John","id":20,"job":"university student"},{"name":"John","id":20,"job":"student at uni still"},{"name":"Jack","id":20,"job":"university student"}]
const map = data.reduceRight((r, e) => {
const key = `${e.name}|${e.id}`;
if (!r.has(key)) r.set(key, e);
return r;
}, new Map);
const uniq = [...map.values()];
console.log(uniq)
I'd reduce into an object, whose keys are the ID and name put together, and whose values are the latest object with a particular ID and name found so far, and then get the object's values:
const input=[{name:"Peter",id:25,job:"carpenter"},{name:"Peter",id:25,job:"shelf maker"},{name:"John",no:20,job:"student"},{name:"John",id:20,job:"university student"},{name:"John",id:20,job:"student at uni still"},{name:"Jack",id:20,job:"university student"}];
const output = Object.values(
input.reduce((a, obj) => {
const { name, id } = obj;
const key = `${name}_${id}`;
a[key] = obj;
return a;
}, {})
);
console.log(output);
Computational complexity is O(N), since there are no nested loops.
You can use reduceRight with a Map to check if the object already exists in the accumulator - if it does, ignore it, else push the new object, and new key + index pair to the map:
const arr = [
{ name: "Peter", id: 25, job: "carpenter" },
{ name: "Peter", id: 25, job: "shelf maker" },
{ name: "John", no: 20, job: "student" },
{ name: "John", id: 20, job: "university student" },
{ name: "John", id: 20, job: "student at uni still" },
{ name: "Jack", id: 20, job: "university student" }
];
const m = new Map([])
const output = arr.reduceRight((a, o, i) => (m.has(o.name + o.id) || a.push(o) && m.set(o.name + o.id, i), a), [])
console.log(output)
However, a regular for loop is the fastest solution here:
const arr = [
{ name: "Peter", id: 25, job: "carpenter" },
{ name: "Peter", id: 25, job: "shelf maker" },
{ name: "John", no: 20, job: "student" },
{ name: "John", id: 20, job: "university student" },
{ name: "John", id: 20, job: "student at uni still" },
{ name: "Jack", id: 20, job: "university student" }
];
const m = new Map([])
const out = []
for (var i = arr.length - 1; i >= 0; i--) {
const o = arr[i]
if (!m.has(o.name + o.id)) {
out.push(o)
m.set(o.name + o.id, i)
}
}
console.log(out)
See the performance test here with a larger, shuffled array.
I wrote a simple algo whose job is to find the corresponding name where the profession is teacher.
The given code calls the function recursively until the given result is achieved.
On executing the code, I am getting the final output is undefined. where as I was expecting the name to be ishan.
Can someone help me in diagnosing the problem in my algo?
//Accessing infitely nested Array
// Infinitely nested Array
const infiniteArray = [
{
name: "Jack",
age: "98",
profession: "doctor",
children: [
{
name: "Varun",
age: "80",
profession: "scientist",
children: [
{
name: "Ishan",
age: "62",
profession: "teacher"
}
]
}
]
}
];
const accessNestedObject = (infiniteArray) => {
return infiniteArray.forEach(element => {
if (element['profession'] === 'teacher') {
console.log(element.name)
return element.name
} else {
console.log(element["children"])
return accessNestedObject(element["children"])
}
});
}
const result = accessNestedObject(infiniteArray)
console.log(result)
You are getting undefined because that's the expected return value of Array#forEach.
You have to declare a variable that will store the final result of your loop.
//Accessing infitely nested Array
// Infinitely nested Array
const infiniteArray = [
{
name: "Jack",
age: "98",
profession: "doctor",
children: [
{
name: "Varun",
age: "80",
profession: "scientist",
children: [
{
name: "Ishan",
age: "62",
profession: "teacher"
}
]
}
]
}
];
const accessNestedObject = (infiniteArray) => {
let result = null;
infiniteArray.forEach(element => {
if (element.profession === 'teacher') {
result = element.name;
} else {
result = accessNestedObject(element.children);
}
});
return result;
}
const result = accessNestedObject(infiniteArray);
console.log(result);
Okay it was a bit hard to explain what I want. Let me explain in more detail. I have an array of objects. Because the "only" identifier of the arrays elements are their indexes, if we want to change an element we need to know which is the target index. But even if we have the index, I don't want to change the whole object, just assign the new one and "merge" them together.
I have a solution, which is ugly, but at least makes more sense what I want:
const users = [
{
id: 0,
name: "John",
hobby: "soccer"
},
{
id: 1,
name: "Alice",
hobby: "squash"
},
{
id: 2,
name: "Greg",
hobby: "guitar"
}
]
const newUsers = [
{
id: 0,
work: "developer"
},
{
id: 2,
work: "musician"
},
{
id: 3,
name: "Roger",
work: "accountant"
}
]
const concatArray = (newArray, oldArray) => {
const objectFromArray = array => array.reduce((object, user) => {
object[user.id] = user;
return object
}, {});
const objectOfOldArray = objectFromArray(oldArray);
const objectOfNewArray = objectFromArray(newArray);
const allIds = Object.keys({...objectOfOldArray, ...objectOfNewArray})
return allIds.map(id => {
const oldProps = objectOfOldArray[id] || {};
const newProps = objectOfNewArray[id] || {};
return {id, ...oldProps, ...newProps}
})
}
console.log(concatArray(newUsers, users))
It works fine, but there should be a more sufficient solution for this. I mean it's a very small operation, adding some properties to the specified objects, but my solution is too over-complicated to earn this. There should be an easier way to earn this.
You can try below approach of Array.forEach
const users = [
{
id: 0,
name: "John",
hobby: "soccer"
},
{
id: 1,
name: "Alice",
hobby: "squash"
},
{
id: 2,
name: "Greg",
hobby: "guitar"
}
]
const newUsers = [
{
id: 0,
work: "developer"
},
{
id: 2,
work: "musician"
},
{
id: 3,
name: "Roger",
work: "accountant"
}
]
let updatedUsers = {};
[...users, ...newUsers].forEach(d => updatedUsers[d.id] = { ...(updatedUsers[d.id] || {}), ...d })
console.log(Object.values(updatedUsers))
Need to push the array object(arr1) valeus into another array object(arr2) if the value not exist. The existing values will not push into another array.
var arr1 = [{
name: 'fred'
}, {
name: 'bill'
}, {
name: 'ted'
}, {
name: 'james'
}];
var arr2 = [{
name: 'spil'
}, {
name: 'fred'
}, {
name: 'bill'
},{
name: 'paul'
}, {
name: 'stone'
}];
function add(name) {
var found = arr1.some(function (el) {
return el.name === name;
});
if (!found) {
arr1.push(arr2);
}
return arr2;
}
Fiddle
You could use a hash table for look up, if the name property is already in arr1. If not push the actual item to arr1.
var arr1 = [{ name: 'fred' }, { name: 'bill' }, { name: 'ted' }, { name: 'james' }],
arr2 = [{ name: 'toString' }, { name: 'spil' }, { name: 'fred' }, { name: 'bill' }, { name: 'paul' }, { name: 'stone' }],
hash = Object.create(null);
arr1.forEach(function (a) {
hash[a.name] = true;
});
arr2.forEach(function (a) {
hash[a.name] || arr1.push(a);
});
console.log(arr1);
PS
Just to make clear, why Object.create(null), a really empty object as hash and not {}, an empty object. Pay attention to the item { name: 'toString' }. In the first part, the item gets inserted, in the second not, because hash has a property with the name toString.
var arr1 = [{ name: 'fred' }, { name: 'bill' }, { name: 'ted' }, { name: 'james' }],
arr2 = [{ name: 'toString' }, { name: 'spil' }, { name: 'fred' }, { name: 'bill' }, { name: 'paul' }, { name: 'stone' }],
hash = {}; // now an object
arr1.forEach(function (a) {
hash[a.name] = true;
});
arr2.forEach(function (a) {
hash[a.name] || arr1.push(a);
});
console.log(arr1);
If you're only appending a single variable, then push() works just fine. If you need to append another array, use concat():
var ar1 = [1, 2, 3];
var ar2 = [4, 5, 6];
var ar3 = ar1.concat(ar2);
alert(ar1);
alert(ar2);
alert(ar3);
Will spit out:
"1,2,3"
"4,5,6"
"1,2,3,4,5,6"
The concat does not affect ar1 and ar2 unless reassigned, for example:
ar1 = ar1.concat(ar2);
alert(ar1);
Will display:
"1,2,3,4,5,6"
Hi check this u can push the first array to other array later can use the underscore unique to return only the unique objects
var arr1 = [{
name: 'fred'
}, {
name: 'bill'
}, {
name: 'ted'
}, {
name: 'james'
}];
var arr2 = [{
name: 'spil'
}, {
name: 'fred'
}, {
name: 'bill'
}, {
name: 'paul'
}, {
name: 'stone'
}];
arr1.push(arr2);
arr1 = _.uniq(arr1, false, function(p) {
return p.name;
});
Use indexOf for get not exist name.Store first your arr1 name as a array !!!
var hasName = arr1.map(function(obj) { return obj.name; });
arr2.filter(function(v,i) { if(hasName.indexOf(v.name) == -1) arr1.push(v); });
console.log(arr1);
If you have the luxury of using ECMAScript 6 then you can create this lovely block
var arr1 = [{
name: 'fred'
}, {
name: 'bill'
}, {
name: 'ted'
}, {
name: 'james'
}];
var arr2 = [{
name: 'spil'
}, {
name: 'fred'
}, {
name: 'bill'
},{
name: 'paul'
}, {
name: 'stone'
}];
arr2.forEach(arr2Item => arr1.find(({ name }) => name === arr2Item.name) || arr1.push(arr2Item));
console.log(arr1);
Given that there's plenty of recursion, you may want to store your data in a different format so you can compare more easily. You could use object hash or ES6 Map to make your life easier. Also to save a few cycles 😁