Javascript array modify value - javascript

I have an array as following.
var vehicle = new Array();
vehicle.push( { "name": "honda", "value": "civic" } );
vehicle.push( { "name": "toyota", "value": "camry" } );
How can I modify this array to change civic to accord?

If you don't know the position of the object in the array, then you can simply loop through the array. When you find the value, replace it and exit the loop. If there could be more than one value of "civic" in the array, then leave out the break; statement and the loop will change all instances of "civic" to "accord".
for(var a = 0, len = vehicle.length; a < len; a++) {
if(vehicle[a].value === "civic") {
vehicle[a].value = "accord";
break;
}
}

Try this
vehicle[0].value = 'accord';
And for the array entirely
vehicle.map(function (vehicle) {
if (vehicle.value === 'civic') {
vehicle.value = 'accord';
}
});

Just do this:
vehicle[0].value = 'accord';

Try vehicle[0].value = "accord"

see JS Fiddle
vehicle[0]['value']='accord';

for (var i = 0, len = vehicle.length; i < len; i++) {
if (vehicle[i].value === "civic") {
vehicle[i].value = "accord";
}
}

Related

JavaScript - count occurrence of strings

I'm looking to count the occurances of certain strings within JSON - in this instance sensorUUID.
var newDataArray = JSON.stringify(conData);
JSON
[{"blobJson":"x","deviceMfg":10,"eventCode":0,"sensorClass":3,"sensorUUID":"22489710","timeStamp":1500362037.111941,"uID":"22489710_3_10"},{"blobJson":"x","deviceMfg":10,"eventCode":0,"sensorClass":3,"sensorUUID":"22489710","timeStamp":1500362036.109874,"uID":"22489710_3_10"}]
I've tried the following code but it is returning an empty object.
var obj = {};
for (var i = 0, j = newDataArray.length; i < j; i++) {
if (obj[newDataArray[i].sensorUUID]) {
obj[newDataArray[i]]++;
}
}
console.log(obj);
The full JSON file will have multiple sensor ID's within it, I am looking to return the number of unique sensor ID.
e.g.
22489710 has 10 occurrences
63846683 has 23 occurrences
etc.
the if condition in for loop is correct but you have to initialize count as 1 for the first time you find a particular sensorUUID.
var newDataArray = [{"blobJson":"x","deviceMfg":10,"eventCode":0,"sensorClass":3,"sensorUUID":"22489710","timeStamp":1500362037.111941,"uID":"22489710_3_10"},{"blobJson":"x","deviceMfg":10,"eventCode":0,"sensorClass":3,"sensorUUID":"22489710","timeStamp":1500362036.109874,"uID":"22489710_3_10"}];
var obj = {};
for (var i = 0, j = newDataArray.length; i < j; i++) {
if (obj[newDataArray[i].sensorUUID]) {
obj[newDataArray[i].sensorUUID]++;
}else{
obj[newDataArray[i].sensorUUID] = 1;
}
}
// obj gives you count for each unique sensorUUID.
console.log(obj);
//if you want total count of all sensorUUID you can sum all the values in obj.
var count = Object.values(obj).reduce((a, b) => a + b, 0);
console.log(count);
you can set a variable count and iterate over the array using Array#forEach and check whether the object has the property sensorUUID using Object#hasOwnProperty if yes, increment the count
var data = [{"blobJson":"x","deviceMfg":10,"eventCode":0,"sensorClass":3,"sensorUUID":"22489710","timeStamp":1500362037.111941,"uID":"22489710_3_10"},{"blobJson":"x","deviceMfg":10,"eventCode":0,"sensorClass":3,"sensorUUID":"22489710","timeStamp":1500362036.109874,"uID":"22489710_3_10"}];
var count = 0;
data.forEach((x)=>{
if(x.hasOwnProperty('sensorUUID'))
count++;
});
console.log(count);
You can simply iterate through the json array using array.reduce and count the occurances of sensorUUID and store it inside the new object.
var json = [{
"blobJson": "x",
"deviceMfg": 10,
"eventCode": 0,
"sensorClass": 3,
"sensorUUID": "22489710",
"timeStamp": 1500362037.111941,
"uID": "22489710_3_10"
}, {
"blobJson": "x",
"deviceMfg": 10,
"eventCode": 0,
"sensorClass": 3,
"sensorUUID": "22489710",
"timeStamp": 1500362037.111941,
"uID": "22489710_3_10"
}, {
"blobJson": "x",
"deviceMfg": 10,
"eventCode": 0,
"sensorClass": 3,
"sensorUUID": "22489710123",
"timeStamp": 1500362036.109874,
"uID": "22489710_3_10"
}];
let count = json.reduce((newObj, obj) => {
if(newObj[obj.sensorUUID]) {
newObj[obj.sensorUUID] = newObj[obj.sensorUUID]+1;
} else {
newObj[obj.sensorUUID] = 1;
}
return newObj;
}, {});
console.log(count);
https://jsfiddle.net/7jjoches/1/
Using jquery method $.parseJSON you have to convert the JSON string to a JSON object and only then you can work with it.
var conData = '[{"blobJson":"x","deviceMfg":10,"eventCode":0,"sensorClass":3,"sensorUUID":"22489710","timeStamp":1500362037.111941,"uID":"22489710_3_10"},{"blobJson":"x","deviceMfg":10,"eventCode":0,"sensorClass":3,"sensorUUID":"22489710","timeStamp":1500362036.109874,"uID":"22489710_3_10"}]';
var newDataArray = $.parseJSON(conData);
console.dir(newDataArray);
var obj = {};
for (var i = 0; i< newDataArray.length; i++) {
obj[newDataArray[i].sensorUUID] = obj[newDataArray[i].sensorUUID] ? obj[newDataArray[i].sensorUUID]+1 : 1;
}
console.log(obj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Javascript transform array into grouped object by value

I have an array:
["car1-coupe", "car2-convertible", "car2-hatchback", "car2-estate", "car3-hatchback", "car3-estate"]
The array can have different sets of cars, and I want to turn it into something like this:
[{
car1: ["car1-coupe"]
},{
car2: ["car2-convertible", "car2-hatchback", "car2-estate"]
},{
car3: ["car3-hatchback", "car3-estate"]
}]
How can I do this in JavaScript or Underscore?
So, assuming an array like this:
var a = ["car1-coupe", "car2-convertible", "car2-hatchback", "car2-estate", "car3-hatchback", "car3-estate"];
You can do this:
var b = a.reduce(function(prev, curr){
var car = curr.split('-')[0]; // "get" the current car
prev[car] = prev[car] || []; // Initialize the array for the current car, if necessary.
prev[car].push(curr); // Add the current item to the array.
return prev;
}, {});
This will return the following object:
{
car1: ["car1-coupe"],
car2: ["car2-convertible", "car2-hatchback", "car2-estate"],
car3: ["car3-hatchback", "car3-estate"]
}
var array = ["car1-coupe", "car2-convertible", "car2-hatchback", "car2-estate", "car3-hatchback", "car3-estate"];
var result = {};
for (var i = 0; i < array.length; i++) {
var key = array[i].split('-')[0]; // The car we're interested in
if (result[key]) { // Check if this car has already been initialized
result[key].push(array[i]); //add this model to the list
} else {
result[key] = [array[i]]; // initialize the array with the first value
}
}
console.log(result);
/*will return :
{
car1: ["car1-coupe"],
car2: ["car2-convertible", "car2-hatchback", "car2-estate"],
car3: ["car3-hatchback", "car3-estate"]
}
*/
var myObj = {}, myArr = [];
for( var i = 0; i < arr.length; i+=1) {
var key = arr[i].split("-")[0];
myObj = {};
myObj[key] = [];
for( var j = i; j < arr.length; j+=1 ) {
if( key === arr[j].split("-")[0])
myObj[key].push(arr[j]);
}
myArr.push(myObj);
}
I think this can be done simply with this way. One loop to get the key and another inner loop to get all values of this key.

How can I slice out all of the array objects containing a value and storing them in a new array

So I have this array and I want to make a new array with those objects that have the swimming value in sports.
var watchesArray = [
{
model: "Swim",
image:"",
price: 149.99,
sports:["Swimming", "Running"]
},
{
model: "FR 10",
image:"",
price: 129.99,
sports:["Running"]
},
{
model: "FR 15",
image:"",
price: 199.99,
sports:["Running"]
},
];
So far I have this but I dont know how to add on to the sliced array with each go around in the for loop. How should I do this?
for (var i = 0; i < watchesArrayLength; i++) {
if (watchesArray[i].sports.indexOf("Swimming") > -1) {
var runningWatchArray = watchesArray.slice(i);
}
}
You can use .filter() method:
watchesArray = [...];
var result = watchesArray.filter(function(watch) {
return watch.sports.indexOf('Swimming') !== -1;
});
If I understand correctly, what you want is
var runningWatchArray = [];
for (var i = 0; i < watchesArrayLength; i++) {
if (watchesArray[i].sports.indexOf("Swimming") > -1) {
var watch = watchesArray.slice(i);
runningWatchArray.push(watch);
}
}
You could also use forEach to loop through each item of the watchesArray...
var runningWatchArray = new Array();
watchesArray.forEach(function(watch){
if (watch.sports.indexOf("Swimming") > -1) {
runningWatchArray.push(watch);
}
}

Get the values by giving key order as a string path JSON

Is there a way to get the value of
{
"first": "first-string",
"second-array": [
{
"first-Obj": 2
}
]
}
is there a way to get or update the values by using a path like string
ex: to change the first-obj's value to 1000
changeTheValueAt('second-array/0/firstObj', 1000)
is there any function like above changeTheValueAt or a method.
Use the following function for that -
function changeTheValueAt(obj, path, value) {
var parts = path.split("/"),
final = obj[parts[0]],
i;
for (i = 1; i < parts.length; i++) {
if (i + 1 < parts.length) {
final = final[parts[i]];
}
else {
final[parts[i]] = value;
}
}
}
and then call it like this -
var ob = {
"first": "first-string",
"second-array": [
{
"first-Obj": 2
}
]
};
changeTheValueAt(ob, "second-array/0/first-Obj", 1000)
alert(ob["second-array"][0]["first-Obj"]);
JSFiddle Demo.
Because second-array is an array, you can't access it by name. You can access it by index or you can iterate over and find a value and change it when found.
var yourObj = {
"first": "first-string",
"second-array": [
{
"first-Obj": 2
}
]
};
yourObject.second-array[0].first-Obj = 1000;
You could do something like:
var changeFirstObj = function(node1, node2, new val){
yourObj[node1].forEach(o, i){
for(var prop in o){
if(prop == node2){
o[node2]=newVal;
}
};
changeFirstObj('second-array', 'first-Obj', 1000);
But that's not really very flexible.

Remove duplicate objects from an array using javascript

I am trying to figure out an efficient way to remove objects that are duplicates from an array and looking for the most efficient answer. I looked around the internet everything seems to be using primitive data... or not scalable for large arrays. This is my current implementation which is can be improved and want to try to avoid labels.
Test.prototype.unique = function (arr, artist, title, cb) {
console.log(arr.length);
var n, y, x, i, r;
r = [];
o: for (i = 0, n = arr.length; i < n; i++) {
for (x = 0, y = r.length; x < y; x++) {
if (r[x].artist == arr[i].artist && r[x].title == arr[i].title) {
continue o;
}
}
r.push(arr[i]);
}
cb(r);
};
and the array looks something like this:
[{title: sky, artist: jon}, {title: rain, artist: Paul}, ....]
Order does not matter, but if sorting makes it more efficient then I am up for the challenge...
and for people who do not know o is a label and it is just saying jump back to the loop instead of pushing to the new array.
Pure javascript please no libs.
ANSWERS SO FAR:
The Performance Test for the answers below:
http://jsperf.com/remove-duplicates-for-loops
I see, the problem there is that the complexity is squared. There is one trick to do it, it's simply by using "Associative arrays".
You can get the array, loop over it, and add the value of the array as a key to the associative array. Since it doesn't allow duplicated keys, you will automatically get rid of the duplicates.
Since you are looking for title and artist when comparing, you can actually try to use something like:
var arrResult = {};
for (i = 0, n = arr.length; i < n; i++) {
var item = arr[i];
arrResult[ item.title + " - " + item.artist ] = item;
}
Then you just loop the arrResult again, and recreate the array.
var i = 0;
var nonDuplicatedArray = [];
for(var item in arrResult) {
nonDuplicatedArray[i++] = arrResult[item];
}
Updated to include Paul's comment. Thanks!
Here is a solution that works for me.
Helper functions:
// sorts an array of objects according to one field
// call like this: sortObjArray(myArray, "name" );
// it will modify the input array
sortObjArray = function(arr, field) {
arr.sort(
function compare(a,b) {
if (a[field] < b[field])
return -1;
if (a[field] > b[field])
return 1;
return 0;
}
);
}
// call like this: uniqueDishes = removeDuplicatesFromObjArray(dishes, "dishName");
// it will NOT modify the input array
// input array MUST be sorted by the same field (asc or desc doesn't matter)
removeDuplicatesFromObjArray = function(arr, field) {
var u = [];
arr.reduce(function (a, b) {
if (a[field] !== b[field]) u.push(b);
return b;
}, []);
return u;
}
and then simply call:
sortObjArray(dishes, "name");
dishes = removeDuplicatesFromObjArray(dishes, "name");
Basic sort-then-unique implementation, fiddle HERE:
function unique(arr) {
var comparer = function compareObject(a, b) {
if (a.title == b.title) {
if (a.artist < b.artist) {
return -1;
} else if (a.artist > b.artist) {
return 1;
} else {
return 0;
}
} else {
if (a.title < b.title) {
return -1;
} else {
return 1;
}
}
}
arr.sort(comparer);
console.log("Sorted: " + JSON.stringify(arr));
for (var i = 0; i < arr.length - 1; ++i) {
if (comparer(arr[i], arr[i+1]) === 0) {
arr.splice(i, 1);
console.log("Splicing: " + JSON.stringify(arr));
}
}
return arr;
}
It may or may not be the most efficient, and should be entirely scalable. I've added some console.logs so you can see it as it works.
EDIT
In the interest of saving on the space the function used, I did that for loop at the end, but it seems likely that didn't properly find only unique results (depsite it passing my simple jsfiddle test). Please try replacing my for loop with the following:
var checker;
var uniqueResults = [];
for (var i = 0; i < arr.length; ++i) {
if (!checker || comparer(checker, arr[i]) != 0) {
checker = arr[i];
uniqueResults.push(checker);
}
}
return uniqueResults;
I use this function. its not doing any sorting, but produces result. Cant say about performance as never measure it.
var unique = function(a){
var seen = [], result = [];
for(var len = a.length, i = len-1; i >= 0; i--){
if(!seen[a[i]]){
seen[a[i]] = true;
result.push(a[i]);
}
}
return result;
}
var ar = [1,2,3,1,1,1,1,1,"", "","","", "a", "b"];
console.log(unique(ar));// this will produce [1,2,3,"", "a", "b"] all unique elements.
Below is Henrique Feijo's answer with ample explanation and an example that you can cut and paste:
Goal: Convert an array of objects that contains duplicate objects (like this one)...
[
{
"id": 10620,
"name": "Things to Print"
},
{
"id": 10620,
"name": "Things to Print"
},
{
"id": 4334,
"name": "Interesting"
}
]
... Into an array of objects without duplicate objects (like this one):
[
{
"id": 10620,
"name": "Things to Print"
},
{
"id": 4334,
"name": "Interesting"
}
]
Explanation provided in the comments:
var allContent = [{
"id": 10620,
"name": "Things to Print"
}, {
"id": 10620,
"name": "Things to Print"
}, {
"id": 4334,
"name": "Interesting"
}]
//Put Objects Into As Associative Array. Each key consists of a composite value generated by each set of values from the objects in allContent.
var noDupeObj = {} //Create an associative array. It will not accept duplicate keys.
for (i = 0, n = allContent.length; i < n; i++) {
var item = allContent[i]; //Store each object as a variable. This helps with clarity in the next line.
noDupeObj[item.id + "|" + item.name] = item; //This is the critical step.
//Here, you create an object within the associative array that has a key composed of the two values from the original object.
// Use a delimiter to not have foo+bar handled like fo+obar
//Since the associative array will not allow duplicate keys, and the keys are determined by the content, then all duplicate content are removed.
//The value assigned to each key is the original object which is along for the ride and used to reconstruct the list in the next step.
}
//Recontructs the list with only the unique objects left in the doDupeObj associative array
var i = 0;
var nonDuplicatedArray = [];
for (var item in noDupeObj) {
nonDuplicatedArray[i++] = noDupeObj[item]; //Populate the array with the values from the noDupeObj.
}
console.log(nonDuplicatedArray)
For those who love ES6 and short stuff, here it's one solution:
const arr = [
{ title: "sky", artist: "Jon" },
{ title: "rain", artist: "Paul" },
{ title: "sky", artist: "Jon" }
];
Array.from(arr.reduce((a, o) => a.set(o.title, o), new Map()).values());
const arr = [
{ title: "sky", artist: "Jon" },
{ title: "rain", artist: "Paul" },
{ title: "sky", artist: "Jon" },
{ title: "rain", artist: "Jon" },
{ title: "cry", artist: "Jon" }
];
const unique = Array.from(arr.reduce((a, o) => a.set(o.title, o), new Map()).values());
console.log(`New array length: ${unique.length}`)
console.log(unique)
The above example only works for a unique title or id. Basically, it creates a new map for songs with duplicate titles.
Below code compares object with JSON as String format and removes duplicates and works fine with simple arrays.
Array.prototype.unique=function(a){
return function(){
return this.filter(a)
}
}(
function(a,b,c){
var tmp=[];
c.forEach(function(el){
tmp.push(JSON.stringify(el))
});
return tmp.indexOf(JSON.stringify(a),b+1)<0
})
If you are using underscore js, it is easy to remove duplicate object.
http://underscorejs.org/#uniq
function remove_duplicates(objectsArray) {
var arr = [], collection = [];
$.each(objectsArray, function (index, value) {
if ($.inArray(value.id, arr) == -1) {
arr.push(value.id);
collection.push(value);
}
});
return collection;
}

Categories