the data.json look like
[
{
"uid": 11111,
"status": "ADMIN"
},
{
"uid": 22222
}
]
i use lodash for find the key uid = 22222
_.find(data, (item)=>item.uid === 22222)
the result is {uid: 22222}
how can i add some status: "value" in result that i find by lodash
i expect like this
[
{
"uid": 11111,
"status": "ADMIN"
},
{
"uid": 22222,
"status": "USER"
}
]
You can use _.find() to get the object, and _.set() to update it:
var data = [{"uid":11111,"status":"ADMIN"},{"uid":22222}];
_.set(_.find(data, function(obj) { return obj.uid === 22222; }), 'value', 'USER');
_.set(_.find(data, function(obj) { return obj.uid === 23322; }), 'value', 'USER'); // no object was found and nothing changed
console.log(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
This gives you the object, so you can just work with it directly:
_.find(data, item => item.uid === 22222).status = "USER";
Otherwise you can get the index and update the entire object.
const idx = _.findIndex(data, item => item.uid === 22222);
data[idx] = Object.assign(data[idx], {status: "USER"});
Depending on the environment you're working in, you don't need to use lodash and you can just use data.find.
You do not need lodash, use Array.prototype.find:
var arr = [
{
"uid": 11111,
"status": "ADMIN"
},
{
"uid": 22222
}
]
// get correct item in array
var item = arr.find(i => i.uid === 22222)
// object is mutable, array have a pointer to the object
item.status = 'USER'
console.log(arr)
Here is a jsbin to play around.
If you are in an old environment (Internet Explorer mostly), use Array.prototype.filter:
// will be undefined if not found, so check for that
var item = arr.filter(i => i.uid === 22222)[0]
Related
I have a array as follows:
data = [
{
"id":1
"name":"london"
},
{
"id":2
"name":"paris"
},
{
"id":3
"name":"london"
},
{
"id":4
"name":"paris"
},
{
"id":5
"name":"australia"
},
{
"id":6
"name":"newzearland"
}
]
At runtime this array can have n number of elements. I want to group this array with respect to name attribute. All the elements with same name should be moved to a separate array. I don't know the what value can name have in advance. This is coming at runtime. For example, from above array I want final output as follows:
output:
newArray1 = [
{
"id":1
"name":"london"
},
{
"id":3
"name":"london"
}
]
newArray2 = [
{
"id":2
"name":"paris"
},
{
"id":4
"name":"paris"
}
]
newArray3 = [
{
"id":5
"name":"australia"
}
]
newArray4 = [
{
"id":6
"name":"newzearland"
}
]
How can I do that?
As Teemu has already pointed out in a comment, creating new variables to store the data is not ideal. You would have no way of knowing how many groups you've created and using variables that you can't be sure exist is not the best way to write code. Fortunately, JavaScript has objects, which can store data like this in a much cleaner way. Here's the code I've come up with:
function groupBy(arr, key) {
let res = {}
for (let element of arr) {
if (res.hasOwnProperty(element[key])) {
res[element[key]].push(element)
} else {
res[element[key]] = [element]
}
}
return res
}
This code is not the best, most efficient code ever, but it is written to be easier to understand for someone still learning. This code loops over every element in your data and checks whether our result already contains an array for elements with that name. If there's already an array for elements with that name, the current element is added to it. If there isn't one, a new one is created with the current element inside it. To do exactly what you want, you'd call this function with groupBy(data, "name") and assign it to a new variable like groupedData (THIS DOES NOT MODIFY THE DATA, IT RETURNS A NEW OBJECT OF GROUPED DATA) .
Start by getting all the unique .names, then map them to the original array filtered by each .name:
const data = [{
"id": 1, "name": "london"
},
{
"id": 2, "name": "paris"
},
{
"id": 3, "name": "london"
},
{
"id": 4, "name": "paris"
},
{
"id": 5, "name": "australia"
},
{
"id": 6, "name": "newzearland"
}
];
const newData = [...new Set(data
//Get all names in an array
.map(({name}) => name))]
//For each name filter original array by name
.map(n => data.filter(({name}) => n === name));
console.log( newData );
//OUTPUT: [newArray1, newArray2, .....]
You can get the expected result with grouping by key approach.
const data = [{"id":1,"name":"london"},{"id":2,"name":"paris"},{"id":3,"name":"london"},{"id":4,"name":"paris"},{"id":5,"name":"australia"},{"id":6,"name":"newzearland"}];
const result = Object.values(data.reduce((acc, obj) =>
({ ...acc, [obj.name]: [...(acc[obj.name] ?? []), obj] }), {}));
console.log(result);
const [newArray1, newArray2, newArray3, newArray4, ...rest] = result;
console.log('newArray1:', newArray1);
console.log('newArray2:', newArray2);
console.log('newArray3:', newArray3);
console.log('newArray4:', newArray4);
.as-console-wrapper{min-height: 100%!important; top: 0}
I am trying to covert an array object into object array with matching filterKey and filterValue of current object.
[
{
"filterKey": "name",
"filterValue": [
{
"value": "abc"
},
{
"value": "def"
}
]
},
{
"filterKey": "status",
"filterValue": [
{
"value": "active"
},
{
"value": "pending"
}
]
}
]
The result I am expecting as below:
{
"name": [
"abc",
"def"
],
"statuses": [
"active",
"pending"
]
}
I tried
obj.map(item => Object.values(item.filterValue))
reduce over the array of data, and create a new object, using map to create a new array of values for each new property.
const data=[{filterKey:'name',filterValue:[{value:'abc'},{value:'def'}]},{filterKey:'status',filterValue:[{value:'active'},{value:'pending'}]}];
// Iterate over the array with `reduce`
const out = data.reduce((acc, obj) => {
// Extract the key and value from each object
const { filterKey: key, filterValue: value } = obj;
// Return the accumulator object updated with the new key
// and array of values gained from `map`
return {...acc, [key]: value.map(o => o.value)};
}, {});
console.log(out);
const oldArr = [{"filterKey": "name","filterValue": [{"value": "abc"},{"value": "def"}]},{"filterKey": "status","filterValue": [{"value": "active"},{"value": "pending"}]}];
const newObj = oldArr.reduce((a, b) => { // reduce to single object
const values = b.filterValue.map(x => x.value); // map the filter values to their strings
if (a[b.filterKey]) a[b.filterKey].concat(values); // if the key already exists add the strings to it (does not apply to your example)
else a[b.filterKey] = values; // else create a new entry with the strings
return a;
}, {});
// if you really want to rename status => statuses
newObj.statuses = newObj.status;
delete newObj.status;
console.log(newObj);
I am trying to get the values of the array of objects using filer in angular but unable to find the solution. Most probably missing something.
channels: {
"channelId": 18,
"platforms": [
{
"name": "android",
"isRecordable": "Y",
},
{
"name": "ios",,
"isRecordable": "Y",
},
{
"name": "pctv",
"isRecordable": "Y",
},
{
"name": "pctv",
"isRecordable": "Y",
},
{
"name": "stb",
"multicastIp": "224.0.251.1",
"multicastPort": 8002,
"isRecordable": "Y"
}
]
}
I want to get the value of a multicast ip where platformName = stb and multicastIp should not be null.
Can someone please explain how to do it.
Use the filter() and find() JavaScript array methods.
//Your array
const platforms = channelConfig.platforms;
const arr = plaforms.filter(platform => { return platform.multicastIp != undefined && platform.name == 'stb' });
let multiCastIps = []
channelconfig.platforms.forEach((platform) => {
if(platform.name == 'stb' && platform.multicastIp != null){
multiCastIps.push(platform)
// pushing only the platforms where name = stb and mltucastip != null
}
});
Short way:
let multiCastIps= channelconfig.platforms.filter(platform => { return platform.name == 'stb' && platform.multicastIp != null});
I would do it like this:
const STB_PLATFORM = "stb";
const stbPlatform = channels.platforms.find(p => p.name == STB_PLATFORM && !!p.multicastIp);
let multicastIP = stbPlatform ? stbPlatform.multicastIp : "Not Available";
The STB_PLATFORM could be a parameter to a search function or a component constant.
This is Browser localstorage Object referred as dataset
let dataset = localStorage.getItem('dataset') !== null ? leech : [];
[
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd"
}
]
This is the initial data object available I want to add more field to a particular id.
This is what I want :
[
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd",
"status":1
}
]
This my code to find the particular id
const user = dataset.find(user => user.id == 456);
Now how can I add status to user and update the user in the dataset?
You've already found the user by using Array.prototype.find() so all you need to do then is add the status property
// const dataset = JSON.parse(localStorage.getItem("dataset"))
const dataset = [{"id":123,"name":"abc"},{"id":456,"name":"bcd"}]
const user = dataset.find(({ id }) => id === 456)
if (user) {
user.status = 1
}
console.info(dataset)
.as-console-wrapper { max-height: 100% !important }
If you then want to store the modified data back into localStorage, use localStorage.setItem() and JSON.stringify()
localStorage.setItem("dataset", JSON.stringify(dataset))
If you want keep dataset initial value, and would like to get a new array, you can use Array.reduce() method.
const dataset = [
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd"
}
]
const output = dataset.reduce((acc, cur) => {
if (cur.id === 456) cur.status = 1;
acc.push(cur);
return acc;
}, []);
console.log(output);
If you want to update dataset, you can use Array.forEach() method.
const dataset = [
{
"id": 123,
"name": "abc"
},
{
"id": 456,
"name": "bcd"
}
]
dataset.forEach(user => {
if (user.id === 456) user.status = 1;
});
console.log(dataset);
You could do with Array#Findindex with callback return function. so could pass the originaldata,searchId and update object. In this method you could updated object easily
Why i suggest findIndex
Because findindex not running entire loop or iteration. If the match
detect on first iteration they will break the loop and returning the
result.For long iteration its more faster than other loop (reduce,forEach)
const data = [ { "id": 123, "name": "abc" }, { "id": 456, "name": "bcd" } ]
function update(dataset,searchId,addtionObject){
let ind = dataset.findIndex(({id}) => id == searchId);
dataset[ind] = {...dataset[ind],...addtionObject}; //join the new and old array
return dataset
}
console.log(update(data,456,{status:1}))
If you want to create new state objet, you can use immer for that.
Immer will produce the nextState based on the mutations to the draft state.
import produce from "immer";
const baseState = [
{
id: 123,
name: "abc",
},
{
id: 456,
name: "bcd",
},
];
const nextState = produce(baseState, (draftState) => {
draftState[1].status = 1;
});
I need to check if the duplicate key value present inside the json array using Angular.js. I am explaining my code below.
var result=[{
"email":'a#gmail.com',
"title":'hello',
"start":'yes'
},{
"email":'a#gmail.com',
"title":'hello',
"start":'yes'
},{
"email":'b#gmail.com',
"title":'ggggg',
"start":'No'
},{
"email":'g#gmail.com',
"title":'hel',
"start":'No'
},{
"email":'b#gmail.com',
"title":'ggggg',
"start":'No'
}];
if (result.length > 0) {
angular.forEach(result,function(obj2){
var data={'title':obj2.mname,'start':obj2.date};
evtArr.push(data);
})
}
Here my requirement is before pushing the data into evtArr it will check the duplicate value using the key- email if one set of value belongs to one email (i.e-a#gmail.com) is already pushed into evtArr then other will remove.
You can use array#reduce and create an object using email as key and object as value. Take out all the values from the object using Object.values().
var result=[{ "email":'a#gmail.com', "title":'hello', "start":'yes' },{ "email":'a#gmail.com', "title":'hello', "start":'yes' },{ "email":'b#gmail.com', "title":'ggggg', "start":'No' },{ "email":'g#gmail.com', "title":'hel', "start":'No' },{ "email":'b#gmail.com',"title":'ggggg', "start":'No' }],
output = Object.values(result.reduce((r,o) => {
r[o.email] = Object.assign({},o);
return r;
},{}));
console.log(output);
Here below is a simple and easy to understand solution for you.
First, push only the results into resultFinal array if the result with same email is not already pushed into that array.
let resultFinal = [];
result.forEach((resI) => {
if (resultFinal.findIndex(resF => resF.email === resI.email) === -1) {
resultFinal.push(result);
}
});
After you have your resultFinal array, run a map and return objects comprising only of title and start for each of the elements.
resultFinal = resultFinal.map((resF) => {
return {title: resultf.title, start: resultf.start};
});
Hope this helps you.
Try this Code.understand easily
var result = [{
"email": 'a#gmail.com',
"title": 'hello',
"start": 'yes'
}, {
"email": 'a#gmail.com',
"title": 'hello',
"start": 'yes'
}, {
"email": 'b#gmail.com',
"title": 'ggggg',
"start": 'No'
}, {
"email": 'g#gmail.com',
"title": 'hel',
"start": 'No'
}, {
"email": 'b#gmail.com',
"title": 'ggggg',
"start": 'No'
}];
if (result.length > 0) {
var ArrayPush = [];
for (i = 0; i < result.length; i++) {
var obj = {}
obj.email = result[i].email;
obj.title = result[i].title;
obj.start = result[i].start;
var Getdistinctdate=ArrayPush.filter(function(element){
return element.email==result[i].email;
});
if(Getdistinctdate.length==0){
ArrayPush.push(obj);
}
}
}