How to remove an object in a JSON object? - javascript

Let me explain.
I got this JSON with many objects:
data = [{"id":"784","label":"blah","publisher":"me"},{"id":"785","label":"bleh","publisher":"you"},{"id":"786","label":"blih","publisher":"she"}];
Ex: I want to remove the object where id = 785
I tried:
$.each( data, function( key, value ) {
if(value.id == '785'){
delete data[key];
}
});
It works, but it changes 'data' structure. Now it seems like this:
data = ["0":{"id":"784","label":"blah","publisher":"me"},"2":{"id":"786","label":"blih","publisher":"she"}]
I'm working with a plugin that does not accept this structure(jQuery UI Autocomplete). So I need to remove the object without changing the 'data' structure.
Any help?

Another way to do it is using filter on the array:
var data = [{"id":"784","label":"blah","publisher":"me"},{"id":"785","label":"bleh","publisher":"you"},{"id":"786","label":"blih","publisher":"she"}];
var result = data.filter(function(x){return x.id !== '785'; });
HTH

That's an array of objects, so try:
for (var i = 0; i < data.length; i++) {
if (data[i].id == 785) {
data.splice(i, 1);
break;
}
}

Try this (fiddle: http://jsfiddle.net/U94Ym/1/):
var i = 0;
while (i < data.length) {
if (data[i].id === "785") {
data.splice(i, 1)
}
else {
i++;
}
}

Related

How to concatenate values of duplicate keys

When reading a csv into a javascript dictionary, how can I concatenate values of what would otherwise be duplicate keys? I've seen answers for how to do this with bash, c#, and perl, but I haven't been able to find answers for Javascript. Here's what I have:
var subjects = {};
d3.csv("test.csv", function(data) {
for (var i = 0; i < data.length; i++)
{
subjects[data[i].Id] = data[i].VALUE;
}
console.log(subjects);
});
This, obviously writes over existing keys. Instead, I want the key to be an array of the values. The csv basically looks like:
Id, VALUE
id1, subject1
id2, subject1
id1, subject3
And I want to output as:
{"id1": ["subject1", "subject3"], "id2": ["subject1"]...}
Just check if your output already has the key, if so you add the new value to the array. Else you create an array.
d3.csv("test.csv", function(data) {
var subjects = {};
for (var i = 0; i < data.length; i++)
{
// Check if key already exists
if(subjects.hasOwnProperty(data[i].Id)){
// push data to array
subjects[data[i].Id].push(data[i].VALUE);
}else{
// create new key and array
subjects[data[i].Id] = [data[i].VALUE];
}
}
console.log(subjects);
});
You could make it into an array and then push the content into that array
var subjects = {};
d3.csv("test.csv", function(data) {
for (var i = 0; i < data.length; i++)
{
//first time we see this id, turn it into an array
if(typeof subjects[data[i].Id] != "object"){
subjects[data[i].Id] = [];
}
//push content to the array
subjects[data[i].Id].push(data[i].VALUE);
}
console.log(subjects);
});
Try this inside the for loop:
typeof subjects[data[i].Id] == 'undefined' && (subjects[data[i].Id] = []);
subjects[data[i].Id].push(data[i].VALUE);
You can reduce the footprint of your code slightly if you use reduce:
var out = data.reduce((p, c) => {
const id = c.Id;
p[id] = p[id] || [];
p[id].push(c.VALUE);
return p;
}, {});
RESULT
{
"id1": [
"subject1",
"subject3"
],
"id2": [
"subject1"
]
}
DEMO

Removing outer array object if an inner array meets a condition

I am dealing with a fairly complex object. It contains 2 arrays, which contain 3 arrays each of objects:
I'm trying to delete one of the history: Array[2] if one of the objects in it has username: null.
var resultsArray = result.history;
var arrayCounter = 0;
resultsArray.forEach(function(item) {
item.forEach(function(innerItem) {
if (innerItem.username == null) {
resultsArray.splice(arrayCounter,1);
};
});
arrayCounter++;
});
Looking through answers it's recommended to do something like:
resultsArray.splice(arrayCounter,1);
This isn't working in this situation because more than one of the objects could have username == null and in that case it will delete multiple history objects, not just the one that I want.
How do I remove only the one specific history array index if username == null?
splice is evil. I think using immutable array methods like filter might be easier to reason about:
x.history =
x.history.filter(function (h) {
return !h.some(function (item) {
return item.username === null
})
})
Go through all the histories, and do not include them in the filter if they have a username that is null.
My understanding was that you only want to delete the first outer array that has an inner array that has an object with a null username. Heres one solution closest to your current form:
var resultsArray = result.history;
var arrayCounter = 0;
var foundFirstMatch = false;
resultsArray.forEach(function(item) {
if (!foundFirstMatch) {
item.forEach(function(innerItem) {
if (innerItem.username == null && !foundFirstMatch) {
foundFirstMatch = true;
};
});
arrayCounter++;
}
});
if (foundFirstMatch > 0)
resultsArray.splice(arrayCounter, 1);
Other syntax:
var resultsArray = result.history;
var outerNdx;
var innerNdx;
var foundMatch = false;
for (outerNdx = 0; !foundMatch && outerNdx < resultsArray.length; outerNdx++) {
for (innerNdx = 0; !foundMatch && innerNdx < resultsArray[outerNdx].length; innerNdx++) {
if (resultsArray[outerNdx][innerNdx].username == null) {
foundMatch = true;
}
}
}
if (foundMatch)
resultsArray.splice(outerNdx, 1);
Update - here's how I'd do it now, without lodash:
thing.history.forEach((arr, i) => {
thing.history[i] = arr.filter( (x) => x.username !== null );
});
Previous answer:
I'd use lodash like this:
_.each(thing.history, function(array, k){
thing.history[k] = _.filter(array, function(v){
return v.username !== null;
})
});
Here's a jsfiddle:
https://jsfiddle.net/mckinleymedia/n4sjjkwn/2/
You should write something like this:
var resultsArray = result.history.filter(function(item){
return !item.some(function(inner){ return inner.username==null; });
});
The foreach loop cant break in this way but a regular for loop can. This is working:
result.history.forEach(function(item) {
loop2:
for (var i = 0; i < item.length; i++) {
var innerItem = item[i];
console.log(innerItem);
break loop2;
}
});

How to delete a specific item/object in localStorage?

Turns out that my localStorage["items"] stored my JSON as a string.
"["{\"itemId\":1, \"itemName\":\"item1\"}", "{\"itemId\":2, \"itemName\":\"item2\"}",
"{\"\":3, \"itemName\":\"item3\"}",]"
This is what it looks like when I JSON.parse(localStorage["items"]):
["{"itemId":1, "itemName":"item1"}", "{"itemId":2, "itemName":"item2"}"
"{"itemId":3, "itemName":"item3"}"]
So in my loop I made it into an object by using jQuery.parseJSON:
var object = jQuery.parseJSON(item[i]);
Right now, what I want to do is delete the object where itemId = 3 and make sure that the object is totally removed from the localStorage.
Here's my Javascript so far:
$("#button_delete").on("click", function(e){
e.preventDefault();
var items = JSON.parse(localStorage.getItem('items'));
for (var i = 0; i < items.length; i++) {
var object = JSON.parse(items[i]);
if(object.request_id == 3){
console.log(items)
delete items[i] // slice doesn't work not sure why
console.log(items)
}
}
item = JSON.stringify(items);
console.log(item);
localStorage.setItem('items', item);
})
UPDATED
When I click the button now, it will delete that item however it will not delete the comma before it.
When I check the localStorage["items"] in the browser it returns this:
"["{\"itemId\":1, \"itemName\":\"item1\"}","{\"itemId\":2, \"itemName\":\"item2\"}",null]"
I have another page that will display the info in the html and it returns the error:
Uncaught TypeError: Cannot read property 'itemId' of null.
So right now is there a way to check or search in localStorage["items"] specifically for ,null and remove it so that the error won't show?
Code on how I'm displaying the info in HTML:
var items = JSON.parse(localStorage.getItem('items'));
var itemsHTML = "";
for(var i = 0; i < items.length; i++){
var object = jQuery.parseJSON(items[i]);
var displayItemId = object.itemId;
var displayItemName = object.itemName;
itemsHTML += "<li id="+displayItemId+">"+displayItemName+"</li>";
}
$("#viewItemList").html(itemsHTML);
All the answers were right but you have to :
Parse the string in localStorage to JSON (you did that)
Remove the item you don't want (with slice() )
Make the JSON to string
Re-set it in the localStorage
So :
1.
var items = JSON.parse(localStorage.getItem("items")); // updated
2.
for (var i =0; i< items.length; i++) {
var items = JSON.parse(items[i]);
if (items.itemId == 3) {
items.splice(i, 1);
}
}
3.
items = JSON.stringify(items); //Restoring object left into items again
4.
localStorage.setItem("items", items);
Parsing to JSON and storing it as string is kinda annoying, but that's the way localStorage works.
Try this one.
$("#button_delete").on("click", function(e){
e.preventDefault();
var items = JSON.parse(localStorage["items"]);
for (var i = 0; i < items.length; i++) {
if(items[i].itemId == 3){
items.splice(i,1);
break;
}
}
})
If you know the key of the specific item - do it short and simple like this:
if (localStorage.getItem('key_to_remove') != null)
localStorage.removeItem('key_to_remove');
localstorage can contain strings only
So first you have to parse items from localstorage (like u do now)
Remove from it the element you don't want.
Serialize it to JSON one more time and store in localstorage.
Here is the approach
var items = localStorage["items"];
for (var i =0; i< items.length; i++) {
var item = JSON.parse(items[i]);
if (item.itemId == 3) {
items.slice(i);
break;
}
}
// Don't forget to store the result back in localStorage
localStorage.setItem("items", items);
eliminar(est: string) {
//estudiantes ES LA KEY
var items = JSON.parse(localStorage.getItem('estudiantes'));
for (var i = 0; i < items.length; i++) {
var item = items[i];
if(item.id == est){
items.splice(i,1);
}
}
items = JSON.stringify(items);
localStorage.setItem('estudiantes', items);
this.getAll();
}

How can I find which index in an array contains an object whose value for a specific key is x? [duplicate]

I would like to find index in array. Positions in array are objects, and I want to filter on their properties. I know which keys I want to filter and their values. Problem is to get index of array which meets the criteria.
For now I made code to filter data and gives me back object data, but not index of array.
var data = [
{
"text":"one","siteid":"1","chid":"default","userid":"8","time":1374156747
},
{
"text":"two","siteid":"1","chid":"default","userid":"7","time":1374156735
}
];
var filterparams = {userid:'7', chid: 'default'};
function getIndexOfArray(thelist, props){
var pnames = _.keys(props)
return _.find(thelist, function(obj){
return _.all(pnames, function(pname){return obj[pname] == props[pname]})
})};
var check = getIndexOfArray(data, filterparams ); // Want to get '2', not key => val
Using Lo-Dash in place of underscore you can do it pretty easily with _.findIndex().
var index = _.findIndex(array, { userid: '7', chid: 'default' })
here is thefiddle hope it helps you
for(var intIndex=0;intIndex < data.length; intIndex++){
eachobj = data[intIndex];
var flag = true;
for (var k in filterparams) {
if (eachobj.hasOwnProperty(k)) {
if(eachobj[k].toString() != filterparams[k].toString()){
flag = false;
}
}
}
if(flag){
alert(intIndex);
}
}
I'm not sure, but I think that this is what you need:
var data = [{
"text":"one","siteid":"1","chid":"default","userid":"8","time":1374156747
}, {
"text":"two","siteid":"1","chid":"default","userid":"7","time":1374156735
}];
var filterparams = {userid:'7', chid: 'default'};
var index = data.indexOf( _.findWhere( data, filterparams ) );
I don't think you need underscore for that just regular ole js - hope this is what you are looking for
var data = [
{
"text":"one","siteid":"1","chid":"default","userid":"8","time":1374156747
},
{
"text":"two","siteid":"1","chid":"default","userid":"7","time":1374156735
}
];
var userid = "userid"
var filterparams = {userid:'7', chid: 'default'};
var index;
for (i=0; i < data.length; i++) {
for (prop in data[i]) {
if ((prop === userid) && (data[i]['userid'] === filterparams.userid)) {
index = i
}
}
}
alert(index);

Finding my object inside JSON by its ID

[
{"ID":"5","Name":"Jay"},
{"ID":"30","Name":"Sharon"},
{"ID":"32","Name":"Paul"}
]
So I have this kind of JSON.
I need to easily supply the value for a required key.
For example:
30 would yield => "Sharon"
5 would yield => "Jay"
etc. What is the right way to do this?
Iterate the array and check if the ID matches
function getById(id) {
var O = null;
for (var i=0; i<arr.length; i++) {
if ( arr[i].ID == id ) return O = arr[i];
}
return O;
}
getById('30'); // returns {"ID":"30","Name":"Sharon"}
FIDDLE
or in newer browsers:
function getById(arr, id) {
return arr.filter(function(o) { return o.ID == id });
}
FIDDLE
Try a linear search:
var searchId = "30";
for(var i = 0; i < json.length; i++)
{
if(json[i].ID == searchId)
{
// Found it.
//
break;
}
}
If the IDs will be unique, and if you're going to need to do this frequently, then you may want to convert your collection to key/value pairs where the ID is the key.
var byId = data.reduce(function(res, obj) {
res[obj.ID] = obj;
return res
}, {});
Now you can simply use the ID to look up the object.
var target = byId["30"];
You could probably just write something to loop through it.
var data = [ {"ID":"5","Name":"Jay"},{"ID":"30","Name":"Sharon"}, {"ID":"32","Name":"Paul"} ];
for(var i in data){
if(data[i]["ID"] == 30){
return data[i]["Name"];
}
}
undersocre.js can find a object in collection by one line code
Reference: http://underscorejs.org/#find
Code:
var people = [
{"ID":"5","Name":"Jay"},
{"ID":"30","Name":"Sharon"},
{"ID":"32","Name":"Paul"}
];
_.find(people, function(person) { return person.ID === '5'; });
FIDDLE

Categories

Resources