Get the difference between two arrays - javascript

I need to get only the difference between two arrays
I tried:
let arr1 = {
"data": [{
"id": "EID_Floss",
"name": "Floss",
"te": "dd"
}]
}
let arr2 = {
"data": [{
"id": "EID_Floss",
"name": "Floss"
}]
}
JSON.stringify(arr2.data.filter((x) => !arr1.data.includes(x)))
Result:
[{
"id": "EID_Floss",
"name": "Floss"
}]
How to get only this:
[{
"te": "dd"
}]

Look at this simpler example:
arr1 = ["foo", "bar"];
arr2 = ["foo", "bar", "foobar"];
arr3 = arr2.filter((x) => !arr1.includes(x));
console.log(arr3);
This does exactly what you exect and the output is:
["foobar"]
The problem with your example, is that the arrays in arr1.data and arr2.data contain objects. You are comparing the object
{
"id": "EID_Floss",
"name": "Floss",
"te": "dd"
}
from arr1 with the object
{
"id": "EID_Floss",
"name": "Floss"
}
from arr2. Since these are not equal, your filter does not remove the object from the array.
Note that this is an all or nothing operation since you are filtering the array of objects. Instead, it sounds like you want to filter the keys in each object. So you need to use Object.keys() or Object.values() to iterate over the contents of the objects.

Related

Updating values of an object within array

I have an array of objects that looks like this:
[
{
"id": 123,
"timeStamp": "\"2019-07-08T20:36:41.580Z\"",
"data": [1, 2, 3]
},
{
"id": 234,
"timeStamp": "\"2019-07-08T20:37:12.472Z\"",
"data": ["Apples", "Oranges"]
}
]
I want to update the value of a particular property of an object within the array but also want to make sure that I return the result in a new array.
How do I do this without running through some type of a loop e.g. for loop?
Say, I want to update the data property of the second object and add Bananas to it.
If you want the result to be a new array, you'll first have to clone the array. This can be more complicated than you might imagine (depending on how deeply you wish to clone things). One way is to use JSON stringify...
Bear in mind that the JSON trick is effectively doing a loop behind the scenes. Inevitable if you want to copy the array, really.
To find the object by ID use Array.find()
let original = [
{
"id": 123,
"timeStamp": "\"2019-07-08T20:36:41.580Z\"",
"data": [1, 2, 3]
},
{
"id": 234,
"timeStamp": "\"2019-07-08T20:37:12.472Z\"",
"data": ["Apples", "Oranges"]
}
]
let copy = JSON.parse(JSON.stringify(original));
copy.find(obj => obj.id === 234).data.push("Bananas");
console.log(copy);
Something like this would do the trick:
let arr = [
{
"id": 123,
"timeStamp": "\"2019-07-08T20:36:41.580Z\"",
"data": [1, 2, 3]
},
{
"id": 234,
"timeStamp": "\"2019-07-08T20:37:12.472Z\"",
"data": ["Apples", "Oranges"]
}
]
arr[1]['data'] = [...arr[1]['data'], 'Bananas']
console.log(arr)
For your example: you can do something like this: say your array of object is saved in test variable
test[1].data.push("Bananas")

javascript array updating using common key

I have 2 javascript arrays with below content:
Array1:
[{"key":"Agents"},{"key":"Formal"},{"key":"Annotation"},{"key":"Business"}]
Array2:
[
{"key":"Agents","class":"newclass","text":"Agents"},
{"key":"Business","class":"newclass1","text":"Business"},
{"key":"Formal","class":"newclass2","text":"Formal"},
{"key":"Annotation","class":"class5","text":"Annotation"},
{"key":"Rate","class":"newclass1","text":"Rates"}
]
The keys in both arrays are same. I am looking to update the array1 with the class and text values from array2 by matching keys.
Is there a way to do it without iterating both the arrays? This is just a small subset of the array. the actual can be a little larger.
Unfortunately, you would need to iterate through both arrays in order to find the right object in each array. Even using built in js prototype methods you would be iterating through the array.
One way you could solve this is my modifying your data structure. Instead of using an array of dictionaries, make a dictionary of dictionaries like so:
First Array:
{
"Agents": {},
"Business": {},
"Formal": {},
"Annotation": {},
"Rate": {}
}
Second Array:
{
"Agents": {
"class": "newclass",
"text": "Agents"
},
"Business": {
"class": "newclass1",
"text": "Business"
},
"Formal": {
"class": "newclass2",
"text": "Formal"
},
"Annotation": {
"class": "newclass5",
"text": "Annotation"
},
"Rate": {
"class": "newclass1",
"text": "Rates"
}
}
Now you can do something like Array1["Agents"] = Array2["Agents"] or however you want to add the data.
You could copy the properties across if you require new objects but it looks like array one is just a filter set of array two - you could simply map the first to every corresponding second. Iterating through both arrays can't be avoided but you can always create a map / ID cache so that you only make a single pass over each.
const arr1 = [
{"key": "Agents"},
{"key": "Formal"},
{"key": "Annotation"},
{"key": "Business"}
]
const arr2 = [
{"key": "Agents", "class": "newclass", "text": "Agents"},
{"key": "Business", "class": "newclass1", "text": "Business"},
{"key": "Formal", "class": "newclass2", "text": "Formal"},
{"key": "Annotation", "class": "class5", "text": "Annotation"},
{"key": "Rate", "class": "newclass1", "text": "Rates"}
]
const transformer = from => {
const cache = from.reduce((map, item) => (
map[item.key] = item, map
), {})
return ({ key }) => cache[key]
}
console.log(
arr1.map(transformer(arr2))
)

How to extract multiple hashtags from a JSON object?

I am trying to extract "animal" and "fish" hashtags from the JSON object below. I know how to extract the first instance named "animal", but I have no idea how to extract both instances. I was thinking to use a loop, but unsure where to start with it. Please advise.
data = '{"hashtags":[{"text":"animal","indices":[5110,1521]},
{"text":"Fish","indices":[122,142]}],"symbols":[],"user_mentions":
[{"screen_name":"test241","name":"Test
Dude","id":4999095,"id_str":"489996095","indices":[30,1111]},
{"screen_name":"test","name":"test","id":11999991,
"id_str":"1999990", "indices":[11,11]}],"urls":[]}';
function showHashtag(data){
i = 0;
obj = JSON.parse(data);
console.log(obj.hashtags[i].text);
}
showHashtag(data);
Use Array.prototype.filter():
let data = '{"hashtags":[{"text":"animal","indices":[5110,1521]},{"text":"Fish","indices":[122,142]}],"symbols":[],"user_mentions":[{"screen_name":"test241","name":"Test Dude","id":4999095,"id_str":"489996095","indices":[30,1111]}, {"screen_name":"test","name":"test","id":11999991, "id_str":"1999990", "indices":[11,11]}],"urls":[]}';
function showHashtag(data){
return JSON.parse(data).hashtags.filter(e => /animal|fish/i.test(e.text))
}
console.log(showHashtag(data));
To make the function reusable, in case you want to find other "hashtags", you could pass an array like so:
function showHashtag(data, tags){
let r = new RegExp(tags.join("|"), "i");
return JSON.parse(data).hashtags.filter(e => r.test(e.text))
}
console.log(showHashtag(data, ['animal', 'fish']));
To get only the text property, just chain map()
console.log(showHashtag(data, ['animal', 'fish']).map(e => e.text));
or in the function
return JSON.parse(data).hashtags
.filter(e => /animal|fish/i.test(e.text))
.map(e => e.text);
EDIT:
I don't really get why you would filter by animal and fish if all you want is an array with ['animal', 'fish']. To only get the objects that have a text property, again, use filter, but like this
let data = '{"hashtags":[{"text":"animal","indices":[5110,1521]},{"text":"Fish","indices":[122,142]}],"symbols":[],"user_mentions":[{"screen_name":"test241","name":"Test Dude","id":4999095,"id_str":"489996095","indices":[30,1111]}, {"screen_name":"test","name":"test","id":11999991, "id_str":"1999990", "indices":[11,11]}],"urls":[]}';
function showHashtag(data){
return JSON.parse(data).hashtags
.filter(e => e.text)
.map(e => e.text);
}
console.log(showHashtag(data));
For me, Lodash can be of great use here, which have different functions in terms of collections. For your case i'd use _.find function to help check the array and get any of the tags with the creteria passed in as second argument like so:
.find(collection, [predicate=.identity], [fromIndex=0])
source npm package
Iterates over elements of collection, returning the first element
predicate returns truthy for. The predicate is invoked with three
arguments: (value, index|key, collection).
with your case this should work
var data = '{ "hashtags": [ { "text": "animal", "indices": [ 5110, 1521 ] }, { "text": "Fish", "indices": [ 122, 142 ] } ], "symbols": [], "user_mentions": [ { "screen_name": "test241", "name": "Test \n Dude", "id": 4999095, "id_str": "489996095", "indices": [ 30, 1111 ] }, { "screen_name": "test", "name": "test", "id": 11999991, "id_str": "1999990", "indices": [ 11, 11 ] } ], "urls": [] }';
var obj = JSON.parse(data);
_.find(obj.hashtags, { 'text': 'animal' });
// => { "text": "animal", "indices": [ 5110, 1521 ] }
For simple parsing like this one, I would use the plain old obj.forEach() method, it is more readable and easy to understand, especially for javascript beginner.
obj = JSON.parse(data).hashtags;
obj.forEach(function(element) {
console.log(element['text']);
});

Converting JSON/JS Object to array

I have a JSON response from my API that is structured like so:
{
"data": [
{
"id": "1", "name": "test"
},
{
"id": "2", "name": "test2"
}
]
}
When I reference data I get the array with each record. I need the curly braces to be brackets due to a plugin I am using requiring it to be an array.
Desired output:
[
["1", "test"],
["2", "test"]
]
How can I convert the above JSON to this?
Edit:
This turned out to be a problem with a plugin I was using, and I knew how to do this fine all along. Thought I was going crazy but my code was fine, some plugin was screwing things up.
You can do this using Array.prototype.map
var arr = json.data.map(function(x){
return [x.id, x.name];
});
Something like this maybe: http://jsfiddle.net/3gcg6Lbz/1/
var arr = new Array();
var obj = {
"data": [
{
"id": "1", "name": "test"
},
{
"id": "2", "name": "test2"
}
]
}
for(var i in obj.data) {
var thisArr = new Array();
thisArr.push(obj.data[i].id);
thisArr.push(obj.data[i].name);
arr.push(thisArr);
}
console.log(arr);

How to sort an array of objects in ascending order of number?

I have an array of objects like the following :
var array = {
"112" : {
"id": "3",
"name": "raj"
},
"334" : {
"id": "2",
"name": "john"
},
"222" : {
"id": "5",
"name": "kelvin"
}
}
Now i want to sort the array in ascending order of id and then restore it in array. I tried using sort() but could not do it. Please help how to do so that when i display the data from the array it comes sorted.
Assuming you meant your code to be an array of objects, ie:
var unsortedArray = [
{ id: 3, name: "raj" },
{ id: 2, name: "john" },
{ id: 5, name: "kelvin" }
];
Then you would be able to sort by id by passing a function to Array.sort() that compares id's:
var sortedArray = unsortedArray.sort(function(a, b) {
return a.id - b.id
});
As others have pointed out, what you have is an object containing objects, not an array.
var array = {
"112" : {
"id": "3",
"name": "raj"
},
"334" : {
"id": "2",
"name": "john"
},
"222" : {
"id": "5",
"name": "kelvin"
}
}
var sortedObject = Array.prototype.sort.apply(array);
result:
{
"112": {
"id": "3",
"name": "raj"
},
"222": {
"id": "5",
"name": "kelvin"
},
"334": {
"id": "2",
"name": "john"
}
}
That isn't an array, it is an object (or would it if it wasn't for the syntax errors (= should be :)). It doesn't have an order.
You could use an array instead (making the current property names a value of a key on the subobjects).
Alternatively, you could use a for loop to build an array of the key names, then sort that and use it as a basis for accessing the object in order.
JavaScript objects are unordered by definition. The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you need things to be ordered, use an array and the Array.prototype.sort method.
That is an object but you can sort an array ilke this:
Working Demo: http://jsfiddle.net/BF8LV/2/
Hope this help,
code
function sortAscending(data_A, data_B)
{
return (data_A - data_B);
}
var array =[ 9, 10, 21, 46, 19, 11]
array.sort(sortAscending)
alert(array);​
Not many people knows that Array.sort can be used on other kinds of objects, but they must have a length property:
array.length = 334;
Array.prototype.sort.call(array, function(a, b) {return a.id - b.id;});
Unfortunately, this doesn't work well if your "array" is full of "holes" like yours.

Categories

Resources