Suppose I have this data:
var id = 81;
var categories = [1, 2, 3, 4, 5];
How do I transform this into:
[{id: 81, category: 1}, {id: 81, category: 2}, {id: 81, category: 3}, {id: 81, category: 4}, {id: 81, category: 5}]
Is there an elegant way to do this using underscore or lodash?
No need for libraries here.
const result = categories.map(x => ({ id, category: x }))
Working Example JSBin
var id = 81;
var categories = [1, 2, 3, 4, 5];
var arr = [];
for (var i = 0; i < categories.length; i++) {
arr.push({id: id, category: categories[i]});
}
Or:
var a = categories.map(function(a) {
return {id: id, category: a};
});
You don't need any library, just good, old Vanilla JS.
var newArray = categories.map(function(item) {
return {id: id, cetegory: item}
});
Using Lo-Dash/Underscore, the code would be:
var result = _.map(categories, x => ({ id, category: x }));
But this is actually longer than the pure JS solution (from Роман Парадеев):
var result = categories.map(x => ({ id, category: x }));
Related
const id = [1, 4, 10]
const data =[{id: 1, name: Banana}, {id: 2, name: Mango}, {id: 3, name: Chili}, {id: 4, name: WaterMelon}, {id: 10, name: WaterMelon}]
I tried filter It's showing me empty value. I want to remove matched by id in an array.
Use filter() with includes():
const result = data.filter(({id}) => !ids.includes(id));
Full snippet:
const ids = [1, 4, 10];
const data = [{
id: 1,
name: 'Banana'
}, {
id: 2,
name: 'Mango'
}, {
id: 3,
name: 'Chili'
}, {
id: 4,
name: 'WaterMelon'
}, {
id: 10,
name: 'WaterMelon'
}];
const result = data.filter(({id}) => !ids.includes(id));
console.log(result);
If you want to filter out matched ID, try this code:
const result = data.filter(({id}) => ids.indexOf(id) < 0);
const ids = [1, 4, 10]
const data =[{id: 1, name: 'Banana'}, {id: 2, name: 'Mango'}, {id: 3, name: 'Chili'}, {id: 4, name: 'WaterMelon'}, {id: 10, name: 'WaterMelon'}];
const result = data.filter(({id}) => ids.indexOf(id) < 0);
console.log(result);
using filter it will select the ids of data,
and your object name type data should be string or maybe you want it as a variable so you will not get error.
data.filter((object) => !id.includes(object.id))
const result=data.filter((value)=>!id.includes(value.id))
I have an array under bahrein that I would like ordered by the index of each item. My bare code is as shown below.
var bahrein = [
{id: 1, name: "Josef"},
{id: 3, name: "Billy"},
{id: 0, name: "Jane"},
{id: 2, name: "Mack"}
];
for (i = 0; i < bahrein.length; i++){
document.getElementById("show").innerHTML += "<p>"+bahrein[i].name+"</p>";
}
<div id="show"></div>
I have ids assigned for each item, but I placed them out of order. What I would like to know is how to programatically use the sort() function to list the names on my list in order.
Right now my innerHTML shows the list in the order they are written (ie: Josef, Billy, Jane, and Mack). I want to show them in the order of their ID (ie: Jane, Josef, Mack, Billy).
You can use sort() method on your data and then append it to html.
var bahrein = [{id: 1, name: "Josef"},{id: 3, name: "Billy"},{id: 0, name: "Jane"},{id: 2, name: "Mack"}];
let show = document.getElementById("show")
bahrein
.sort((a, b) => a.id - b.id)
.forEach(e => show.innerHTML += `<p>${e.name}</p>`)
<div id="show"></div>
You could also create string of sorted html and then append it html.
var bahrein = [{id: 1, name: "Josef"},{id: 3, name: "Billy"},{id: 0, name: "Jane"},{id: 2, name: "Mack"}];
let sorted = bahrein
.sort((a, b) => a.id - b.id)
.map(e => `<p>${e.name}</p>`)
.join('')
document.getElementById("show").innerHTML = sorted
<div id="show"></div>
It doesn't answer your question, but you can use "lodash" to do the same.
var bahrein = [
{id: 1, name: "Josef"},
{id: 3, name: "Billy"},
{id: 0, name: "Jane"},
{id: 2, name: "Mack"}
];
bahrein = _.orderBy(bahrein , ['id'],['asc']);
You can learn more about it here.
I have two arrays of same length
ids = [123, 456, 789, ...., 999];
names = ['foo', 'bar', ... , 'zzz'];
I want to create an array like
[ {id: 123, name: 'foo'}, {id: 123, name: 'bar'}, ..., {id: 999, name: 'zzz'} ]
I am trying to avoid forEach if possible.
Any suggestions?
Is map okay?
ids = [123, 456, 789, 999];
names = ['foo', 'bar', 'baz', 'zzz'];
result = ids.map(function(_, i) {
return {id: ids[i], name: names[i]}
});
console.log(result)
If you don't want to use any higher-order functions, then just do this:
var objects = [];
for (var i = 0; i < ids.length; i++) {
objects.push({id: ids[i], name: names[i]});
}
No need for forEach here. Use map which is similar to forEach.
var ids = [123, 456, 999];
var names = ['foo', 'bar', 'zzz'];
var result = ids.map(function (currentId, index) {
return {
id: currentId,
name: names[index]
};
});
console.log(result);
The forEach version would look like this (notice how similar they are):
var ids = [123, 456, 999];
var names = ['foo', 'bar', 'zzz'];
var result = [];
ids.forEach(function(currentId, index) {
result.push({
id: currentId,
name: names[index]
});
});
console.log(result);
The below code uses foreach but you dont need to handle it. I hope this will work for you.
ids = [123, 456, 789, 999];
names = ['foo', 'bar', 'zab', 'zzz'];
result = ids.map(function(_, i) {
return {id: ids[i], name: names[i]}
});
console.log(result)
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.
I have two arrays of objects like this:
var arr1 = [{Id: 1, Name: "Test1"}, {Id: 2, Name: "Test2"}, {Id: 3, Name: "Test3"}, {Id: 4, Name: "Test4"}]
var arr2 = [{Id: 1, Name: "Test1"}, {Id: 3, Name: "Test3"}]
I need to compare the elements of the two arrays by Id and remove the elements from arr1 that are not presented in arr2 ( does not have element with that Id). How can I do this ?
var res = arr1.filter(function(o) {
return arr2.some(function(o2) {
return o.Id === o2.Id;
})
});
shim, shim, shim.
You can use a function that accepts any number of arrays, and returns only the items that are present in all of them.
function compare() {
let arr = [...arguments];
return arr.shift().filter( y =>
arr.every( x => x.some( j => j.Id === y.Id) )
)
}
var arr1 = [{Id: 1, Name: "Test1"}, {Id: 2, Name: "Test2"}, {Id: 3, Name: "Test3"}, {Id: 4, Name: "Test4"}];
var arr2 = [{Id: 1, Name: "Test1"}, {Id: 3, Name: "Test3"}, {Id: 30, Name: "Test3"}];
var arr3 = [{Id: 1, Name: "Test1"}, {Id: 6, Name: "Test3"}, {Id: 30, Name: "Test3"}];
var new_arr = compare(arr1, arr2, arr3);
console.log(new_arr);
function compare() {
let arr = [...arguments]
return arr.shift().filter( y =>
arr.every( x => x.some( j => j.Id === y.Id) )
)
}
Making use of a hash (a Set) will give a performance gain:
var arr1 = [{Id: 1, Name: "Test1"}, {Id: 2, Name: "Test2"},
{Id: 3, Name: "Test3"}, {Id: 4, Name: "Test4"}];
var arr2 = [{Id: 1, Name: "Test1"}, {Id: 3, Name: "Test3"}];
arr1 = arr1.filter(function (el) {
return this.has(el.Id);
}, new Set(arr2.map(el => el.Id)));
console.log(arr1);
A new Set is created that gets the Id values from arr2:
"1","3"
That Set is passed as the thisArg to filter, so that within the filter callback it is available as this.