Extract from arrays the common elements in javascript - javascript

i have a question about arrays in javascript using jquery and knockout js.
I have this structure in my code:
var MyModel = function(model) {
var self = this;
self.FirstArray = ko.observableArray(ko.utils.arrayMap(model.FirstArray, function(object){
return new ArrayObj(object);
}));
/*--here's the code that i need to implement--*/
}
var ArrayObj = function(obj){
var self = this;
self.VarX = obj.VarX;
self.SeccondArray = ko.observableArray(ko.utils.arrayMap(obj.SeccondArray, function(seccond){
return new Object2(seccond);
}));
}
var Object2 = function(obj2) {
var self = this;
self.IdObj2 = obj2.IdObj2;
self.Name = obj2.Name;
}
The problem is that i need another array, that depends on the items that are in common between the Object2 arrays in SeccondArray.
In an example, its something like this:
Array1 = [{IdObj2: 1, Name: "A"},
{IdObj2: 2, Name: "B"},
{IdObj2: 3, Name: "C"}]
Array2 = [{IdObj2: 1, Name: "A"},
{IdObj2: 3, Name: "C"}]
Array3 = [{IdObj2: 3, Name: "C"}]
FirstArray = [{VarX: J, Array1},
{VarX: K, Array2},
{VarX: L, Array3}]
So.. the array that i need, must have:
ResultArray = [{IdObj2: 3, Name: "C"}]
Because {IdObj2: 2, Name: "C"} it's the only common between them.
I hope you can help me with this.

What you are looking for is an intersection. I used a library called underscore and used a nifty object intersection I found here How to use underscore's "intersection" on objects?
here is the fiddle with it working
http://jsfiddle.net/sujesharukil/vyguB/
_.intersectionObjects = _.intersect = function(array) {
var slice = Array.prototype.slice; // added this line as a utility
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.any(other, function(element) { return _.isEqual(element, item); });
});
});
};
var Array1 = [{IdObj2: 1, Name: "A"},
{IdObj2: 2, Name: "B"},
{IdObj2: 3, Name: "C"}],
Array2 = [{IdObj2: 1, Name: "A"},
{IdObj2: 3, Name: "C"}],
Array3 = [{IdObj2: 3, Name: "C"}];
var result = _.intersectionObjects(Array1, Array2, Array3);
console.log(result);
Hope that helps.
Cheers!

Related

jquery move an item in object from one position to another

I got and object of objects like this:
var obj = {
0:{id: 1, name: 'one'},
1:{id: 2, name: 'two'},
2:{id: 3, name: 'three'},
3:{id: 4, name: 'four'}
};
I need to move an item under the key 1 from its current position to position 4 (where an item with id: 4 is), so it should look like the following:
var obj = {
0:{id: 1, name: 'one'},
1:{id: 3, name: 'three'},
2:{id: 4, name: 'four'},
3:{id: 2, name: 'two'},
};
The problem is that it is an object of objects, not an array. If it were an array I could do it with the help of the following function:
function array_move(arr, old_index, new_index) {
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
};
But in this case I get the following error:
Uncaught TypeError: arr.splice is not a function
Any ideas how to fix it would be welcome. Thank you.
Create an array of keys and values and then order them:
var keys = Object.keys(obj);
var values = Object.values(obj);
var newObj = {};
values = array_move(values);
keys.forEach(function(el, i){
newObj[el] = values[i];
});

Convert two arrays into an object

var foo = { "a": [1,2,3] }
var bar = { "b": [7,8,9] }
output should look like this
[ {a: 1, b: 7}, {a: 2, b: 8}, {a:3, b: 9}]
How can I do this using ramda or javascript functional programming ?
I have done this using for loop i = 0, is it possible using functional ramda programming
If both arrays are always the same length, you can do this using map.
function mergeArrays(arr1, arr2) {
return arr1.map(function(item, index) {
return {
a: arr1[index], //or simply, item
b: arr2[index]
};
});
}
var a = [1, 2, 3];
var b = [7, 8, 9];
var joined = mergeArrays(a, b);
document.getElementById('result').innerHTML = JSON.stringify(joined, null, 2);
<pre id="result">
</pre>
You can achieve this using R.transpose to convert an array of [[1,2,3], [7,8,9]] to [[1, 7], [2, 8], [3, 9]] and then map over it with R.zipObj.
const fn = R.compose(
R.map(R.zipObj(["a", "b"])),
R.transpose
)
const a = [1, 2, 3], b = [7, 8, 9]
const result = fn([a, b])
console.log(result)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
If you would prefer to pass a and b as two arguments to fn rather than an array then you can swap R.transpose in the example above with R.unapply(R.transpose).
Assuming you want [{a:1,b:7},{a:2,b:8},{a:3,b:9}] it can be done pretty easily with map using the index to get the value in b:
var result = a.map((v, i) =>({ a: v, b: b[i] }));
i am having an array
const peopleObject = { "123": { id: 123, name: "dave", age: 23 },
"456": { id: 456, name: "chris", age: 23 }, "789": { id: 789, name:
"bob", age: 23 }, "101": { id: 101, name: "tom", age: 23 }, "102":
{ id: 102, name: "tim", age: 23 } }
for this particular i have created a code that convrts array to object i hope this is usefull for you
const arrayToObject = (array) =>
array.reduce((obj, item) => {
obj[item.id] = item
return obj
}, {})
const peopleObject = arrayToObject(peopleArray)
console.log(peopleObject[idToSelect])
Your expected output doesn't have a valid format. You should store the data in array. Like ,
var output = [];
var a = [1,2,3], b = [7,8,9];
for(var i=0; i< a.length; i++){
var temp = {};
temp['a'] = a[i];
temp['b'] = b[i];
output.push(temp);
}
You cannot store the result in an object the way you want. Objects are key-value pairs. But what you expect is only the values without keys which is not possible!
create function form ramda's addIndex and map
const data = { keys: ['a', 'b', 'c'], values: ['11', '22', '33'] }
const mapIndexed = R.addIndex(R.map)
const result = mapIndexed((item, i) => {
return { [item]: data.values[i] }
}, data.keys)
You will get an array of objects

angularjs converting json object to array

Hi I have json return object like this
color_selected = [
{ id: 4},
{ id: 3}
];
how do I convert it to
color_selected = [4,3]
thank you for your any help and suggestions
You could iterate through it like this:
var newArray = [];
for(var i = 0; i < color_selected.length; i++) {
newArray.push(color_selected[i].id);
}
you can use javascript map function for that
var newArray = color_selected.map(o=> o.id)
var color_selected = [
{ id: 4},
{ id: 3}
];
var newArray = color_selected.map(o=> o.id)
console.log(newArray)
color_selected = [
{ id: 4},
{ id: 3}
];
You can use lodash
// in 3.10.1
_.pluck(color_selected, 'id'); // → [4, 3]
_.map(color_selected, 'id'); // → [4, 3]
// in 4.0.0
_.map(color_selected, 'id'); // → [4, 3]
Use Array.map() method with ES6 Arrow operator.
var color_selected = [
{ id: 4},
{ id: 3}
];
color_selected = color_selected.map(item => {return item.id });
console.log(color_selected);

reducing key values of an array

I have an array like
var myArray = [{ques: 1, ans: "A"},
{ques: 2, ans: "D"},
{ques: 3, ans: "C"}];
I want to convert it as a new array like:
var newArray= [{1: "A"}, {2: "D"}, {3: "C"}]
Please help me to achieve it.
UPDATE
I have realized that working with newArray is really difficult.OOPS!
it would be meaningful to convert it to
var newArray=[1: "A", 2: "D", 3: "C"]
Please help me in it.
Array.prototype.map() function should do the job:
var myArray = [{ques: 1, ans: "A"}, {ques: 2, ans: "D"}, {ques: 3, ans: "C"}],
newArr = myArray.map(function (o) {
var newObj = {};
newObj[o.ques] = o.ans;
return newObj;
});
console.log(newArr);
Use map function
const mappedArr = myArray.map(elem => {
return {[elem.ques] : elem.ans};
})
You could use Array#map with a computed property.
var myArray = [{ ques: 1, ans: "A" }, { ques: 2, ans: "D" }, { ques: 3, ans: "C" }],
newArray = myArray.map(a => ({ [a.ques]: a.ans }));
console.log(newArray);
Use map to transform each element of the array:
var myArray = [ {ques: 1, ans: "A"},
{ques: 2, ans: "D"},
{ques: 3, ans: "C"}];
var newArray = myArray.map(function(it) {
var ret = {};
ret[it.ques] = it.ans;
return ret;
});

How to remove the same object in two arrays with lodash or underscore?

Now I have two object arrays,
var arr1 = [{id: 0, name: 'Jack'}, {id: 1, name: 'Ben'}, {id: 2, name: 'Leon'}, {id: 3, name: 'Gavin'}];
var arr2 = [{id: 0, name: 'Jack'}, {id: 5, name: 'Jet'}, {id: 2, name: 'Leon'}];
I want to remove those objects of same id in arr1 and arr2, so the results are:
var arr1 = [{id: 1, name: 'Ben'}, {id: 3, name: 'Gavin'}];
var arr2 = [{id: 5, name: 'Jet'}];
How to implement it with lodash or underscore?
Here are my implementation.
arr1_ids = _.pluck(arr1, 'id');
arr2_ids = _.pluck(arr2, 'id');
same_ids = _.intersection(arr1_ids, arr2_ids);
arr1 = _.remove(arr1, function(e) { return !_.contains(same_ids, e.id); });
arr2 = _.remove(arr2, function(e) { return !_.contains(same_ids, e.id); });
Is there any better way to do that?
Can you use _.difference?
same_elements = _.intersection(arr1, arr2);
arr1 = _.difference(arr1, same_elements);
arr2 = _.difference(arr2, same_elements);
I'm not sure how this should be done with underscore or lodash, but here's a JavaScript implementation.
It creates a filter function that you can then apply to both arrays to only keep the elements that aren't part of the intersection.
var arr1 = [{id: 0, name: 'Jack'}, {id: 1, name: 'Ben'}, {id: 2, name: 'Leon'}, {id: 3, name: 'Gavin'}];
var arr2 = [{id: 0, name: 'Jack'}, {id: 5, name: 'Jet'}, {id: 2, name: 'Leon'}];
var negative_intersection_filter = function(a, b) {
// create a map to speed up the filtering later
var map = a.reduce(function(map, current) {
// perform the intersection
map[current.id] = b.some(function(item) {
return item.id == current.id;
});
return map;
}, {});
// our filtering function, simple
return function(item) {
return !map[item.id];
}
}(arr1, arr2);
// apply the filter here
arr1 = arr1.filter(negative_intersection_filter);
arr2 = arr2.filter(negative_intersection_filter);
console.log(arr1);
console.log(arr2);
I think your algorithm is about right, here's a slightly different approach in plain js. I've used a, b instead of arr1, arr2 for brevity:
// Collect ids and sort
var ids = a.map(function(obj) {return obj.id}).concat(b.map(function(obj) {return obj.id})).sort();
// Get IDs that aren't duplicates
var nonDups = ids.filter(function(v, i, o){return v !== o[i-1] && v !== o[i+1]});
// Keep only the non-duplicates in each array
a.reduceRight(function(pre, cur, i, o){if (nonDups.indexOf(cur.id) == -1) o.splice(i, 1)},0);
b.reduceRight(function(pre, cur, i, o){if (nonDups.indexOf(cur.id) == -1) o.splice(i, 1)},0);
JSON.stringify(a) // [{"id":1,"name":"Ben"},{"id":3,"name":"Gavin"}]
JSON.stringify(b) // [{"id":5,"name":"Jet"}]
reduceRight is just used to iterate over each array backwards so that splicing doesn't affect the iteration.

Categories