reducing key values of an array - javascript

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;
});

Related

Filtering an array of values by array of object's value

In Javascript we have an array:
let arr1 = [1, 2, 3, 4, 5];
...and an array of objects:
let arr2 = [ {name: "banana", id: 1},
{name: "mango", id: 3} ];
I want to remove all the elements from arr1 where arr2's id = arr1's value and return an array like this:
[2, 4, 5]
Here is what I've tried, but it doesn't seem to work.
let newArr = arr1.filter(
x => !arr2.includes(e => e.id === x)
)
How can I achieve this? I can use lodash as well as ES6.
The .includes() method doesn't allow you to pass a method into it to define equality. You can use .some() instead, which does allow you to specify this:
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [
{name: "banana", id: 1},
{name: "mango", id: 3}
];
const newArr = arr1.filter(x => !arr2.some(e => e.id === x))
console.log(newArr);
A more efficient approach would be to grab all the id properties from the objects in your array and put then in a Set for quick look-up. Then use .filter() with .has() like so:
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [
{name: "banana", id: 1},
{name: "mango", id: 3}
];
const idSet = new Set(arr2.map(({id}) => id));
const newArr = arr1.filter(x => !idSet.has(x))
console.log(newArr);
You can first create a temporary of id and age, then use filter() with includes()
let arr1 = [1, 2, 3, 4, 5];
let arr2 = [ {name: "banana", id: 1},
{name: "mango", age: 3} ];
let temp = arr2.map(i => i.id || i.age);
let res = arr1.filter(i => !temp.includes(i));
console.log(res);
let arr1 = [1, 2, 3, 4, 5];
let arr2 = [ {name: "banana", id: 1},
{name: "mango", id: 3} ];
arr1.map((item,index) =>
arr2.map(object => {
if(item == object.id) arr1.splice(index,1)
})
)
console.warn(arr1) /// output [2, 4, 5]

Remove same Values from array of Object

I want to remove same object from array by comparing 2 arrays.
Sample Data:
arr1 = [
{id: 1, name: "a"},
{id: 2, name: "b"},
{id: 3, name: "c"},
{id: 4, name: "d"},
];
arr2 = [
{id: 1, name: "a"},
{id: 4, name: "d"},
];
let newArray = []; // new array with with no same values it should be unique.
arr1.map((val, i)=>{
arr2.map((val2)=>{
if(val.id == val2.id){
console.log('Matched At: '+ i) // do nothing
}else{
newArray.push(val);
}
})
})
console.log(newArray); // e.g: [{id: 2, name: "b"}, {id: 3, name: "c"},];
Array.filter combined with not Array.some.
The trick here is also to not some,..
const arr1 = [
{id: 1, name: "a"},
{id: 2, name: "b"},
{id: 3, name: "c"},
{id: 4, name: "d"},
], arr2 = [
{id: 1, name: "a"},
{id: 4, name: "d"},
];
const newArray=arr1.filter(a=>!arr2.some(s=>s.id===a.id));
console.log(newArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }
As mentioned in comments the question could be interpreted slightly differently. If you also want the unqiue items from arr2, you basically just do it twice and join. IOW: check what not in arr2 is in arr1, and then check what not in arr1 that's in arr2.
eg..
const notIn=(a,b)=>a.filter(f=>!b.some(s=>f.id===s.id));
const newArray=[...notIn(arr1, arr2), ...notIn(arr2, arr1)];
Update 2:
Time complexity, as mentioned by qiAlex there is loops within loops. Although some will short circuit on finding a match, if the dataset gets large things could slow down. This is were Set and Map comes in.
So to fix this using a Set.
const notIn=(a,b)=>a.filter(a=>!b.has(a.id));
const newArray=[
...notIn(arr1, new Set(arr2.map(m=>m.id))),
...notIn(arr2, new Set(arr1.map(m=>m.id)))
];
const isInArray = (arr, id, name) => arr.reduce((result, curr) => ((curr.name === name && curr.id === id) || result), false)
const newArray = arr1.reduce((result, curr) => (isInArray(arr2, curr.id, curr.name) ? result : result.concat(curr)), [])
You can update you code using filter() method, instead of using .map() method like:
const arr1 = [
{id: 1, name: "a"},
{id: 2, name: "b"},
{id: 3, name: "c"},
{id: 4, name: "d"},
], arr2 = [
{id: 1, name: "a"},
{id: 4, name: "d"},
];
let newArray = []; // new array with with no same values it should be unique.
newArray = arr1.filter(function(a) {
for(var i=0; i < arr2.length; i++){
if(a.id == arr2[i].id) return false;
}
return true;
});
console.log(newArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You check each element in first array whether its id lies in the second array by using Array.prototype.some. If the element is not present then only yield it.
const arr1 = [
{id: 1, name: "a"},
{id: 2, name: "b"},
{id: 3, name: "c"},
{id: 4, name: "d"},
];
const arr2 = [
{id: 1, name: "a"},
{id: 4, name: "d"},
];
const result = arr1.filter(x => !arr2.some(y => y.id === x.id));
console.log(result);
I think a simple comparer can works for getting differences and then concat them.
with this method you dont need to check which array is bigger.
arr1 = [ {id: 1, name: "a"}, {id: 2, name: "b"}, {id: 3, name: "c"}, {id: 4, name: "d"}];
arr2 = [ {id: 1, name: "a"}, {id: 4, name: "d"},];
function localComparer(b){
return function(a){
return b.filter(
function(item){
return item.id == a.id && item.name == a.name
}).length == 0;
}
}
var onlyInArr1 = arr1.filter(localComparer(arr2));
var onlyInArr2 = arr2.filter(localComparer(arr1));
console.log(onlyInArr1.concat(onlyInArr2));
We can filter values by checking whether some element is not contained in current array:
const result = arr1.reduce((a, c) => {
if (!arr2.some(a2 => a2.id === c.id))
a.push(c);
return a;
}, [])
An example:
let arr1 = [
{id: 1, name: "a"},
{id: 2, name: "b"},
{id: 3, name: "c"},
{id: 4, name: "d"},
];
let arr2 = [
{id: 1, name: "a"},
{id: 4, name: "d"},
];
const result = arr1.reduce((a, c) => {
if (!arr2.some(a2 => a2.id === c.id))
a.push(c);
return a;
}, [])
console.log(result);
Try this one -
const arr1 = [
{id: 1, name: "a"},
{id: 2, name: "b"},
{id: 3, name: "c"},
{id: 4, name: "d"},
];
const arr2 = [
{id: 1, name: "a"},
{id: 4, name: "d"},
];
const arr3 = [...arr1, ...arr2];
const mySubArray = _.uniq(arr3, 'id');
console.log(mySubArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
So many loops in every answer.
Complexity of the code my answer is 2N,
Idea is:
to merge arrays.
first loop - mark duplicates somehow
second loop - filter duplicates out
arr1 = [
{id: 1, name: "a"},
{id: 2, name: "b"},
{id: 3, name: "c"},
{id: 4, name: "d"},
];
arr2 = [
{id: 1, name: "a"},
{id: 4, name: "d"},
];
let newArray = [...arr1, ...arr2].reduce((acc, item, index) => {
acc.items.push(item);
if (typeof acc.map[item.id] !== 'undefined') {
acc.items[acc.map[item.id]] = null;
acc.items[index] = null;
}
acc.map[item.id] = index;
return acc
}, {map: {}, items: []}).items.filter(item => !!item)
console.log(newArray);

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);

Extract from arrays the common elements in 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!

Categories