how to get a single field from array - javascript

I am using an array like below
var types = [{id:1, type:'Type 2'}, {id:2, type:'Type 5'}, {id:3, type:'Type 1'}, {id:4, type:'Type 2'}];
I want to filter values based on Type and get that into a single dimension array. I tried using filter etc. but gets the filtered 2-dimensional array.
$filter('filter')(types, { type: 'Type 2' })
Result should be just id array without type like:
[{id:1}, {id:4}]

Try with Array#map after the filter the array
var types = [{id:1, type:'Type 2'}, {id:2, type:'Type 5'}, {id:3, type:'Type 1'}, {id:4, type:'Type 2'}];
console.log(types.filter(a=> a.type =='Type 2' ).map(a=> ({id : a.id})))

true to its naming convention filter() will not manipulate object; it selects a new subset array.
You can use Array.map()
$filter('filter')(types, { type: 'Type 2' }).map(function(x){
return { id : x.id };
})
Working Fiddle :http://jsfiddle.net/ADukg/12074/

You can either use a combination of filter and map. Or, you can use this amazing function called reduce which can single-handedly filter as well as map your array. Like this:
var types = [{id:1, type:'Type 2'}, {id:2, type:'Type 5'}, {id:3, type:'Type 1'}, {id:4, type:'Type 2'}];
var res = types.reduce(function(arr, obj) {
if(obj.type === 'Type 2') {
arr.push({
id: obj.id
})
}
return arr
}, [])
console.log(res)

Hi Vikas Vaidya you can also use the following code to solve this problem:
function filterArrayofObjects(objKey, objValue) {
var temp = [], count = -1;
for (var i in types) {
var flag = false;
var obj = {};
for (var j in types[i]) {
if (j === objKey && types[i][j] === objValue) {
flag = true;
continue;
}
obj[j] = types[i][j];
}
if (flag) {
count++;
temp[count] = obj;
}
}
return temp;
}
var result = filterArrayofObjects("type", "Type 2");
window.console.log(result);

You can use Underscore js. _.filter and _.map can help you to achieve desired results

Related

compare two array of objects and perform if condition using foreach

I am trying to compare two arrays of objects, after comparing I need to perform some conditions like if the item id matches in both the array.
After this I need to return nothing if it is false I need to return some value.
I am trying to achieve this by using foreach. The reason for using foreach is that I need to apply the condition and I need to return something.
I need to check each value in both arrays to apply the condition.
I tried with some map methods but some are returning a boolean and I couldn't apply the condition by using that. I got partial output by using foreach but looping the second array returns undefined.
I need to compare these two arrays and I need to find the items which have the same ID for these items I need to return null, for the items which are having different IDs I need to return some value. Hence I need to compare each element in the array of objects and need to apply the condition
Could anyone let me know what am I missing? Thanks in advance!
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'johnny#example.com'},
{id:4, name:'Bobby', email:'bobby#example.com'}
];
result1.forEach((num1, index) => {
// console.log(num1.id) //result coming as expected
const num2 = result2[index];
console.log("num2", num2.id)
// console.log(num1.id, num2.id);//here I need to compare result 1 ID and result2 id of each element
});
Not sure that you really have to use Array#forEach. Depending on what you need to return you can use other methods such as Array#find as in the demo below and return the result1 element or a property of it or null.
const result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
],
result2 = [
{id:2, name:'John', email:'johnny#example.com'},
{id:4, name:'Bobby', email:'bobby#example.com'}
],
output = result1
.map(({id}) => [id, result2.find(o => o.id === id) || null]);
console.log( output );
You were probably getting an error because while you're iterating through result1, you'll eventually get to index === 2, and then const num2 = result2[index] is undefined, because result2 doesn't have that many elements, and anything like num2.id will throw an error.
I'm not totally sure what you're trying to achieve, but it sounds like you want to iterate through the first array, and find a matching element in the second array, then do something with them if there is a match, otherwise do nothing.
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'johnny#example.com'},
{id:4, name:'Bobby', email:'bobby#example.com'}
];
const doSomethingWithMatches = (arr1, arr2) => {
// Loop through each item in the first array
arr1.forEach(item => {
// Find an item in the second array with the same id
const matchingItem = arr2.find(item2 => item2.id === item.id);
// If there is a match, do something with them
if (matchingItem) {
console.log(item, matchingItem);
}
});
};
doSomethingWithMatches(result1, result2);
you can filter by id, and same name. Then change the value.
const mergedResults = result1.map((result1Item) => {
const result2Item = result2.find((item) => item.id === result1Item.id);
return {
...result1Item,
...result2Item,
};
output like this:
[
{ id: 1, name: 'Sandra', type: 'user', username: 'sandra' },
{
id: 2,
name: 'John',
type: 'admin',
username: 'johnny2',
email: 'johnny#example.com'
},
{ id: 3, name: 'Peter', type: 'user', username: 'pete' },
{
id: 4,
name: 'Bobby',
type: 'user',
username: 'be_bob',
email: 'bobby#example.com'
}
]

Remove objects with empty values from array / Javascript

I have an array of objects:
let arr = [{id:0, value: 'zero'},
{id:1, value: 'one'},
{id:2, value: ''}]
I need to remove object with empty value. What I am trying:
const removeEmpty = (arr) => {
let filtered = arr.filter(val => val.value != '');
return filtered;
};
Stuck with this:
TypeError: Cannot read property 'filter' of undefined
Edit: corrected syntax
IMHO, you are looking for something like this:
var arr = [{id:0, value: 'zero'}, {id:1, value: 'one'}, {id:2, value: ''}];
var filteredArr = arr.filter(obj => obj.value != '')
console.log(filteredArr);
NOTE: Your's is not a proper array (because Objects inside it are invalid).
You missed a comma on the value of id and a quote for the value of the value property
let arr = [{id:0, value: "zero"},
{id:1, value: "one"},
{id:2, value: ''}];
console.log(arr.filter(a => a.value != ''));
Seems your arr is not correct i.e object key value pair is not valid
let arr = [{id:0, value: 'zero'}, {id:1, value: 'one'}, {id:2, value: ''}];
const removeEmpty = (arr) => {
let filtered = arr.filter(val => val.value !== '');
return filtered;
}
removeEmpty(arr)
This questions is already answered in below link, Please have a look
Click here!
Following code will be helpful in more cases, for instance if object value is: false, null, empty string or undefined.
let arr = [
{id:0, value: 'zero'},
{id:1, value: 'one'},
{id:2, value: ''},
{id:3, value: false},
{id:4, value: null},
{id:5}
];
const filteredArr = arr.filter(obj => obj.value);
console.log(filteredArr);

How to find parent nodes path from flattened array?

I have flattened hierarchy array as follows.
I'd like to get path to the specific node as array.
var arr = [
{id:1, parent_id:null},
{id:2, parent_id:1},
{id:3, parent_id:null},
{id:4, parent_id:2},
{id:5, parent_id:4}
]
getPath(arr, 5) return [1,2,4]
Do you have any suggestion?
You could use a hash table for all id and their parents and iterate until no parent is available.
function getPath(nodes, id) {
var parents = Object.create(null),
path = [];
nodes.forEach(function (n) {
parents[n.id] = n.parent_id;
});
while (id = parents[id]) {
path.unshift(id);
}
return path;
}
var array = [{ id: 1, parent_id: null }, { id: 2, parent_id: 1 }, { id: 3, parent_id: null }, { id: 4, parent_id: 2 }, { id: 5, parent_id: 4 }];
console.log(getPath(array, 5)); // [1, 2, 4]
Here is my simple answer for what you want to achieve:
var arr = [
{id:1, parent_id:null},
{id:2, parent_id:1},
{id:3, parent_id:null},
{id:4, parent_id:2},
{id:5, parent_id:4}
];
var res=[];
function getPath(arr, x){
for(var i=0; i<arr.length; i++){
if(arr[i].id== x){
getPath(arr, arr[i].parent_id);
if(arr[i].parent_id !== null){
res.push(arr[i].parent_id);
}
}
}
}
getPath(arr, 5);
console.log(res);
I have just used recursion and it works great.
Recursive function to get the desired output.
var arr = [
{id:1, parent_id:null},
{id:2, parent_id:1},
{id:3, parent_id:null},
{id:4, parent_id:2},
{id:5, parent_id:4}
]
let resultArr = [];
function getPath(arr, num) {
for(var i in arr) {
if(arr[i].id === num) {
//console.log(num);
getPath(arr, arr[i].parent_id);
resultArr.push(num);
break;
}
}
return resultArr.slice(0, (resultArr.length - 1));
}
var res = getPath(arr, 5);
console.log(res);
You could define a recursive function that finds the item in the array with an id value matching the provided key parameter, and then checks if the current item has a parent_id truthy value.
If there is a parent_id:
The function will define results as an array if it wasn't passed into the function, and will then add the current item's parent_id to the front of the results array. Next, it will call itself with the following three parameters:
The starting array (arr).
The current item's parent_id as the key to look at next.
The results array as the array to return when completely done.
If there is no parent_id:
The function will instead return the results array.
var arr = [
{id:1, parent_id:null},
{id:2, parent_id:1},
{id:3, parent_id:null},
{id:4, parent_id:2},
{id:5, parent_id:4}
];
function getPath(arr, key, results) {
var nextObj = arr.filter(function(obj){
return obj.id == key;
})[0];
if(nextObj && nextObj.parent_id) {
results = typeof results !== 'object' ? [] : results;
var nextKey = nextObj.parent_id;
results.unshift(nextKey);
return getPath(arr, nextKey, results);
}
return results;
}
console.log(getPath(arr, 5));

Filter an array of objects and extract its property by using an array of keys

im having this problem which i cant wrap around my head,
much better if put in a code.
//Array of objects sample
var objects = [{id:1, name:'test1'}, {id:2, name:'test2'}, {id:3, name: 'test3'}, {id:4, name:'test4'}];
var arrayOfKeys = [3,1,4];
//extract object name property if its id property is equivalent to one of arrayOfKeys [3,1]
//var arrayOfKeys = [3,1,4];
//output sample: extractedName=['test3','test1','test4'];
i've been using filter and map but no avail, also tried nesting filter inside map im getting an arrays of array and inside is a single object.
You could map the objects and ren map the wanted keys for getting the name.
var objects = [{ id: 1, name: 'test1' }, { id: 2, name: 'test2' }, { id: 3, name: 'test3' }],
arrayOfKeys = [3, 1],
result = arrayOfKeys.map((map => id => map.get(id).name)(new Map(objects.map(o => [o.id, o]))));
console.log(result);
I assume you need to map array numbers to id properties? Here's the code where you map through numbers and find inside your array to handle situations when there's no such id in objects array:
var objects = [{id:1, name:'test1'}, {id:2, name:'test2'}, {id:3, name: 'test3'}];
var arrayOfKeys = [3,1];
var res = arrayOfKeys.map(key => {
var found = objects.find(o => o.id == key);
return found ? found.name : false;
})
console.log(res)
let objects = [{id:1, name:'test1'}, {id:2, name:'test2'}, {id:3, name: 'test3'}, {id:4, name:'test4'}],
arrayOfKeys = [3,1,4];
let result = objects.reduce((res, obj) => { // loop over the array of objects
let index = arrayOfKeys.indexOf(obj.id); // check if the current object's id is in the array of keys
if(index !== -1) { // if it's there
res.push(obj.name); // then add the current object's name to the result array
arrayOfKeys.splice(index, 1); // remove its id from the array of keys so we won't search for it again (optional, slightly better than leaving it there)
}
return res;
}, []);
console.log(result);
I think you were on the right track with the filter. You can make it readable and concise with some.
var objects = [{id: 1,name: 'test1'}, {id: 2,name: 'test2'}, {id: 3,name: 'test3'}, {id: 4,name: 'test4'}],
arrayOfKeys = [3, 1, 4];
var result = objects.filter((x, i) => {
if (arrayOfKeys.some(k => x.id === k)) {
return true;
}
})
console.log(result.map(x=>x.name));
Something even shorter! would be
var objects = [{id: 1,name: 'test1'}, {id: 2,name: 'test2'}, {id: 3,name: 'test3'}, {id: 4,name: 'test4'}],arrayOfKeys = [3, 1, 4];
var result = objects.filter((x, i) => arrayOfKeys.some(k => x.id === k));
console.log(result.map(x=>x.name));

Update Multiple Objects in Nested Arrays

I have an array of multi dimensional objects:
var arr = [
{
id: '10c',
name: 'item 1'
children: [
{id: '11v', name: 'Item 1 child 1'},
{id: '12c', name: 'Item 1 child 2'}
]
},
{
id: '13v',
name: 'item 2'
children: [
{id: '26e', name: 'Item 2 child 1'},
{id: '7a', name: 'Item 2 child 2'}
]
}
]
and another object of data:
var array = [
{id: '12c', name: 'New name 1'},
{id: '26e', name: 'New name 2'},
{id: '11v', name: 'New name 3'},
];
If I want to update the name value of the respective objects in arr, based on the id value in array, how would be the best way of doing that?
arr might be more than 2 levels deep, so I would like to be able to do it without having to nest multiple forEach
Try this:
function update(items, id, name) {
var item;
for (var i = 0; i < items.length; i++) {
item = items[i];
if (item.id === id) {
item.name = name;
return;
}
if (item.children) {
update(item.children, id, name);
}
}
}
Then:
update(arr, '11v', 'test');
Updating by array:
array.forEach(function (item) {
update(arr, item.id, item.name);
});
Use a recursive solution and make use of the inherent mutability of Javascript.
First build up a flat map representation of all the objects.
function createObjectMap(array) {
var map = {};
array.forEach(function(obj) {
map[obj.id] = obj;
if(obj.children) {
Object.assign(map, createObjectMap(obj.children));
}
});
return map;
}
Now you've got a map of id -> object you can use. They reference the same mutable objects, so you can mutate them in place and know that they'll also update in the original data structure.
function update(map, updates) {
updates.forEach(function(update) {
map[update.id].name = update.name;
});
}
This conversion to O(1) lookup time means you don't have to write any searching logic.
You could use angular $filter to do the same
//to get element
function getFiltered(collection, obj){
var filtered = $filter('filter')(collection, obj, true);
if(filtered[0])
return filtered[0]
if(collection.children)
return getFiltered(collection.children, obj, true);
}
angular.forEach(array, function(element){
var filtered = getFiltered(array, { id: element.id })
if(filtered[0]) filtered.name = element.name;
})

Categories