I have array of objects like this:
[{key: 4214, value: 'example'}, ...etc
And i have some kind of template, that i want to use for generate a new array for objects.
{type: 1, blocks: []} //one item in blocks
{type: 2, blocks: []} //two items in blocks arr
{type: 3, blocks: []} //four items in blocks arr
I need to create an array based on a template, using data from an existing array.
In each of the templates types a limited specified number of objects can fit into the blocks object. When the loop creates all three types from the template, it must start over from type one. In type: 1 one object, two in type: 2, and four in type: 3
For example, the effect I want to achieve is the creation of new array from this [{key: 1}, {key: 2}, {key: 3}]
to this [{type: 1, blocks: [{key: 1}]}, {type: 2, blocks: [{key: 2}, {key: 3}]}]
If there were more objects, the next one object in new array will be type: 3, which blocks will contain 4 elements. And then, it starts again from type: 1. As a result, an array of any size must be transformed according to the logic of the template. sorry for my language, this is a super complicated explanation for me. if something is not clear, I will answer almost instantly
You can implement based on 7 items as one unit as follows.
const input = [{key: 1}, {key: 2}, {key: 3}, {key: 4}, {key: 5}, {key: 6}, {key: 7}, {key: 8}, {key: 9}];
const result = [];
for (let i = 0; i < input.length; i += 7) {
const item = [];
// Add Type1
item.push({
type: 1,
blocks: [ input[i] ]
});
// Add Type2
if (i + 1 < input.length) {
item.push({
type: 2,
blocks: [ input[i + 1] ]
});
}
if (i + 2 < input.length) {
item[1].blocks.push(input[i + 2]);
}
// Add Type3
if (i + 3 < input.length) {
item.push({
type: 3,
blocks: [ input[i + 3] ]
});
}
for (let subI = i + 4; subI < Math.min(i + 7, input.length); subI ++) {
item[2].blocks.push(input[subI]);
}
result.push(...item);
}
console.log(result);
Related
const my_arr = [
{id: 1, arr: [{subId: 1, value: 1}],
{id: 2, arr: [{subId: 2, value: 2}],
{id: 3, arr: [{subId: 3, value: 1}],
]
how do I map over this array my_arr and then map over arr to return an array like so:
[
{subId: 1, value: 1},
{subId: 3, value: 1},
]
basically filtering out only where values are 1 and then returning only that sub object
I've tried doing
my_arr.map((x) => x.map((y) => y.value === 1 ? y : null))
You can try this approach with flatMap and filter
const my_arr = [
{id: 1, arr: [{subId: 1, value: 1}]},
{id: 2, arr: [{subId: 2, value: 2}]},
{id: 3, arr: [{subId: 3, value: 1}]},
]
const result = my_arr.flatMap(item => item.arr).filter(item => item.value === 1)
console.log(result)
Your current approach maps over the outer array my_arr, and then uses an inner map to map over the inner array. Since .map() always returns an array, you'll end up mapping your objects from your outer array to other arrays, which you don't want. You can instead use .flatMap() which will combine/join the returned inner arrays into one array. However, rather than using .map() as your inner method though, you should use .filter() to create an array of objects that have a value of 1, which then gets merged into your resulting outer array created by the .flatMap() method:
const my_arr = [ {id: 1, arr: [{subId: 1, value: 1}]}, {id: 2, arr: [{subId: 2, value: 2}]}, {id: 3, arr: [{subId: 3, value: 1}]}, ];
const res = my_arr.flatMap(({arr}) => arr.filter(({value}) => value === 1));
console.log(res);
Since you are dealing with nested structure, you will have to get little creative.
First you will have to filter the array.
Inside it, you can use .some to check if your condition matches and return matching
Now you have the filtered list but you still need to format your output. You can use .reduce and concat arr of every item
This will be useful if you have multiple items in arr.
const my_arr = [
{id: 1, arr: [{subId: 1, value: 1}] },
{id: 2, arr: [{subId: 2, value: 2}] },
{id: 3, arr: [{subId: 3, value: 1}] },
]
const output = my_arr
.filter(({ arr }) =>
arr.some(({value}) => value === 1)
).reduce((acc, { arr }) => acc.concat(arr), [])
console.log(output)
I am facing problem to merge the two arrays. I have two arrays of objects first is prev having old values and another with updated values. I would like to have result array with all the objects of prev array with its updated value in array next, and also have objects in next array.
Example:
var prev = [{id: 1, val: 'abc'}, {id: 2, val: 'pqr'}];
var next = [{id: 1, val: 'nextVal'}, {id: 3, val: 'xyz'}];
expected
mergeOutput = [
{id: 1, val: 'nextVal'}, // value is updated
{id: 2, val: 'pqr'},
{id: 3, val: 'xyz'}
]
Note: Array order do not matter.
You can use Map() to merge array.
var prev = [{id: 1, val: 'abc'}, {id: 2, val: 'pqr'}];
var next = [{id: 1, val: 'nextVal'}, {id: 3, val: 'xyz'}];
var hash = new Map();
prev.concat(next).forEach(function(obj) {
hash.set(obj.id, Object.assign(hash.get(obj.id) || {}, obj))
});
var mergedArray = Array.from(hash.values());
console.log(mergedArray);
Source : StackOverflow
I have two arrays:
array a:
var a = [
{
id: 1,
name: 'a'
},
{
id: 2,
name: 'b'
},
{
id: 3,
name: 'c'
}
];
array ids:
var ids = [1];
I want to array a filtered by array ids, result i wanted:
var a = [
{
id: 1,
name: 'a'
}
];
The most important thing is i want the change on the original array, rather than return a new array.
underscore solution is better:)
You can use .filter
a = a.filter(function(el){
return ~ids.indexOf(el.id)
});
// should give you [{id: 1, name: 'a'}]
Today I tried to solve similar task (filtering the original array of objects without creating a new array) and this is what I came up with:
const a = [{ id: 1, name: 'a'}, { id: 2, name: 'b'}, { id: 3, name: 'c'}];
const ids = [1];
Array.from(Array(a.length).keys()).reverse().forEach(index =>
!ids.some(id => id === a[index].id) && a.splice(index, 1)
);
console.log(a); // [{ id: 1, name: 'a'}]
The point is that we need to loop back through the original array to be able to use Array.prototype.splice, but I didn't want the for-loop, I wanted to have ES6 one-liner. And Array.from(Array(a.length).keys()).reverse() gives me a list of reversed indexes of the original array. Then I want to splice the original array by current index only if the corresponding item's id is not present in the ids array.
I have an array with some objects
var arr = [{index: 1, type: 2, quantity: 1}, {index: 3, type: 1, quantity: 2}, {index: 1, type: 3, quantity: 3}];
Now I want to search my array if exists an object inside it with a given index and type. If exists, I add + 1 to the quantity property. If not, I add a new object with quantity of 1. I tried to use, $.grep and $.inArray but to no avail. What is the best way to search the properties in an array of objects?
tnx!
For loop with if condition: JsFiddle
var arr = [{index: 1, type: 2}, {index: 3, type: 1}];
var found = '';
for(item in arr){
if(arr[item].index === 1 && arr[item].type === 2){
found = arr[item];
}
}
In the function in grep you need to return the result of the test and also the result returned from grep is a new array. It does not modify the existing array.
I made a snippet:
var arr = [{index: 1, type: 2}, {index: 3, type: 1}, {index: 1, type: 3}];
var result = $.grep(arr, function(e){
return e.index === 1 && e.type === 3
});
alert(result[0].index + " " + result[0].type);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I have a stupid problem that at first seems to be simple to solve, but turns out to be tricky.
I have an array of objects, each with two properties: id and value:
[
{id: 2, value: 10},
{id: 4, value: 3},
{id: 2, value: 2},
{id: 1, value: 15}
]
I want to write an algorithm that sums up the values of ones with similar id.
My end result should be a new array with only the merged objects:
[
{id: 2, value: 12},
{id: 4, value: 3},
{id: 1, value: 15}
]
I've tried the following, but it doesn't work:
var arr = [];
arr.push({id: 2, visit:10});
arr.push({id: 4, visit:3});
arr.push({id: 2, visit:2});
arr.push({id: 1, visit:15});
// Deep copy
var copy = jQuery.extend(true, [], arr);
var masterArr = [];
for (var i = 0; i < arr.length; i++) {
var objArr = [];
objArr.push(arr[i]);
for (var j = copy.length-1; j > -1; j--) {
if (arr[i].id === copy[j].id) {
var q = copy.splice(j,1);
}
}
masterArr.push(objArr);
}
My plan was to first gather all similar objects in separate arrays (objArr), sum them up and put them in an end array (masterArr). I use jquerys extend to make a deep copy (not a reference) and reverse iteration and splice to remove objects thats already been found as "duplicates".
This doesn't work! And it doesn't seem to be a very efficient mehtod to solve my problem.
How could I do this? Performance isn't top priority but rather "nice to have"!
Thanks!
You can do it like this:
// Assuming:
a = [{id: 2, value: 10}, {id: 4, value: 3}, {id: 2, value: 2}, {id: 1, value: 15}]
var b = {}, // Temporary variable;
c = []; // This will contain the result;
// Build a id:value object ( {1: 15, 2: 12, 4: 3} )
a.map(function(current){b[current.id] = (b[current.id] || 0) + current.value});
for(var key in b){ // Form that into the desired output format.
c.push({id: parseInt(key, 10), value: b[key]});
}
console.log(c);
/* [{id: 1, value: 15},
{id: 2, value: 12},
{id: 4, value: 3}] */
I'm using parseInt(key, 10), since the keys are strings, you'll probably want them converted to integers again.
// First group the data based on id and sum the values
var temp = data.reduce(function(result, current) {
result[current.id] = (result[current.id] || 0) + current.value;
return result;
}, {});
// then recreate the objects with proper id and value properties
var result = [];
for (var key in temp) {
result.push({
id: parseInt(key, 10),
value: temp[key]
});
}
console.log(result);
Output
[ { id: 1, value: 15 },
{ id: 2, value: 12 },
{ id: 4, value: 3 } ]
The quickest approach loops over the array only once using Array.prototype.filter():
var tmp = {},
result = arr.filter(function (el) {
if (tmp.hasOwnProperty(el.id)) {
tmp[el.id].visit += el.visit;
return false;
}
else {
tmp[el.id] = el;
return true;
}
});
It also reuses the objects, though this renders the original array to contain inaccurate values. If this is a problem, you can modify the example to copy each object property to a new object.