Given a collection, how can I remove only the first item that matches a condition?
For example, given this collection:
[
{ id: 1, name: "don" },
{ id: 2, name: "don" },
{ id: 3, name: "james" },
{ id: 4, name: "james" }
]
Filter out the first result that matches { name: "james" }.
Result:
[
{ id: 1, name: "don" },
{ id: 2, name: "don" },
{ id: 4, name: "james" }
]
Using underscore.js _.without and _.findWhere
var myarray = [
{ id: 1, name: "don" },
{ id: 2, name: "don" },
{ id: 3, name: "james" },
{ id: 4, name: "james" }
];
var arr = _.without(myarray, _.findWhere(myarray, {
name: "james"
}));
console.log(arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
Using Lodash _.without and _.find
var myarray = [
{ id: 1, name: "don" },
{ id: 2, name: "don" },
{ id: 3, name: "james" },
{ id: 4, name: "james" }
];
var result =_.without(myarray, _.find(myarray, { name: "james" }));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Are you are looking a solution like this?
Iterate and update an array using Array.prototype.splice.
var arr = [
{ id: 1, name: "don" },
{ id: 2, name: "don" },
{ id: 3, name: "james" },
{ id: 4, name: "james" }
];
// loop and remove the first match from the above array
for (i = 0; i < arr.length; i++) {
if (arr[i].name == "james"){
arr.splice(i, 1);
break;
}
}
// write into the browser console
console.log(arr);
with Lodash
var newArray = _.without(array, _.find(array, { name: "james" }));
Related
states = [{
name: telangana,
cities: [{
id: 1,
name: foo
}, {
id: 2,
name: joo
}, {
id: 3,
name: goo
}]
},
{
name: punjab,
cities: [{
id: 4,
name: tyu
}, {
id: 5,
name: ery
}, {
id: 6,
name: doo
}]
},
{
name: mumbai,
cities: [{
id: 7,
name: eee
}, {
id: 8,
name: qqq
}, {
id: 9,
name: www
}]
},
]
I want response like [foo, joo, goo, tyu, ery,doo, eee,qqq,www]
Can someone help me ?
Just write one line:
Learn more about reduce() and map()
const states = [{ name: "telangana", cities: [{ id: 1, name: "foo" }, { id: 2, name: "joo" }, { id: 3, name: "goo" }] }, { name: "punjab", cities: [{ id: 4, name: "tyu" }, { id: 5, name: "ery" }, { id: 6, name: "doo" }] }, { name: "mumbai", cities: [{ id: 7, name: "eee" }, { id: 8, name: "qqq" }, { id: 9, name: "www" }] }, ];
const result = states.reduce((acc, { cities }) => [...acc, ...cities.map(({ name }) => name)], []);
console.log(result);
const getNames = (data) => {
const nameArr = [];
data.forEach((ele) => {
ele.cities.forEach((ele2) => {
nameArr.push(ele2.name);
})
})
return nameArr;
}
getNames(states);
Try this please!
states = [{
name: "telangana",
cities: [{
id: 1,
name: "foo"
}, {
id: 2,
name: "joo"
}, {
id: 3,
name: "goo"
}]
},
{
name: "punjab",
cities: [{
id: 4,
name: "tyu"
}, {
id: 5,
name: "ery"
}, {
id: 6,
name: "doo"
}]
},
{
name: "mumbai",
cities: [{
id: 7,
name: "eee"
}, {
id: 8,
name: "qqq"
}, {
id: 9,
name: "www"
}]
},
]
const wantedArray = []
for(i=0; i < states.length; i++){
for(j=0; j < states[i].cities.length; j++){
wantedArray.push(states[i].cities[j].name)
}
}
console.log(wantedArray)
Just give it an empty array, then you loop through the states indexes, each index in states will have a cities array, then you just need to loop it again in that array to get each name of the cities. From then, you are using the push method that Javascript provides to push it to the empty array.
Here's how I'm doing it in JSFiddle, there will have a better way to do this, too.
It's actually about mapping an array of objects and grouping it. Is there any way to convert this array the javascript way without lodash
let fruits = [
{
id: 1,
expired_date: "2021-11-30",
name: "mango"
},
{
id: 2,
expired_date: "2021-11-20",
name: "kiwi"
},
{
id: 3,
expired_date: "2021-11-20",
name: "orange"
},
{
id: 4,
expired_date: "2021-11-10",
name: "banana"
},
{
id: 5,
expired_date: "2021-11-10",
name: "apple"
}
]
grouped to something like this? (grouped by a key in the object, wrapped in an object with 2 keys, one contains the category and the other contains the objects relevant to the group)
let fruits = [
{
expired_date: "2021-11-30",
rows: [
{
id: 1,
expired_date: "2021-11-30",
name: "mango"
}
]
},
{
expired_date: "2021-11-20",
rows: [
{
id: 2,
expired_date: "2021-11-20",
name: "kiwi"
},
{
id: 3,
expired_date: "2021-11-20",
name: "orange"
}
]
},
{
expired_date: "2021-11-10",
rows: [
{
id: 4,
expired_date: "2021-11-10",
name: "banana"
},
{
id: 5,
expired_date: "2021-11-10",
name: "apple"
}
]
}
]
I've read this question but it's not quite the same as expected
Array.reduce should work
const fruits = [ { id: 1, expired_date: "2021-11-30", name: "mango" }, { id: 2, expired_date: "2021-11-20", name: "kiwi" }, { id: 3, expired_date: "2021-11-20", name: "orange" }, { id: 4, expired_date: "2021-11-10", name: "banana" }, { id: 5, expired_date: "2021-11-10", name: "apple" }];
const result = Object.values(fruits.reduce((acc, item) => {
(acc[item.expired_date]??={expired_date: item.expired_date, rows: []}).rows.push(item);
return acc;
}, {}));
console.log(result);
Revised without ??= assignment, it's not supported in IE.
const result = Object.values(fruits.reduce((acc, item) => {
if (acc[item.expired_date]) {
acc[item.expired_date].rows.push(item);
} else {
acc[item.expired_date] = {expired_date: item.expired_date, rows: [item]};
}
return acc;
}, {}));
I have an array of objects here:
const arr = [
{ id: 1, name: "test1", quantity:1 },
{ id: 2, name: "test2", quantity:1 },
{ id: 2, name: "test3", quantity:1 },
{ id: 3, name: "test4", quantity:1 },
{ id: 4, name: "test5", quantity:1 },
{ id: 5, name: "test6", quantity:1 },
{ id: 5, name: "test7", quantity:1 },
{ id: 6, name: "test8", quantity:1 }
];
I want to add quantities of the duplicate objects together before removing them
So the result is:
const arr = [
{ id: 1, name: "test1", quantity:1 },
{ id: 2, name: "test3", quantity:2 },
{ id: 3, name: "test4", quantity:1 },
{ id: 4, name: "test5", quantity:1 },
{ id: 5, name: "test6", quantity:2 },
{ id: 6, name: "test8", quantity:1 }
];
I have seen variations of it done removing duplicates using map or reduce but I haven't seen anything that can what I want to accomplish in an eloquent way without using too many loops.
I have been thinking about how to best accomplish this all day and haven't found anything, any help would be appreciated
You can use reduce with an object to store the element with each id.
const arr = [
{ id: 1, name: "test1", quantity:1 },
{ id: 2, name: "test2", quantity:1 },
{ id: 2, name: "test3", quantity:1 },
{ id: 3, name: "test4", quantity:1 },
{ id: 4, name: "test5", quantity:1 },
{ id: 5, name: "test6", quantity:1 },
{ id: 5, name: "test7", quantity:1 },
{ id: 6, name: "test8", quantity:1 }
];
const res = Object.values(
arr.reduce((acc,curr)=>{
acc[curr.id] = acc[curr.id] || {...curr, quantity: 0};
acc[curr.id].quantity += curr.quantity;
return acc;
}, {})
);
console.log(res);
const arr = [
{ id: 1, name: "test1", quantity: 1 },
{ id: 2, name: "test2", quantity: 1 },
{ id: 2, name: "test3", quantity: 1 },
{ id: 3, name: "test4", quantity: 1 },
{ id: 4, name: "test5", quantity: 1 },
{ id: 5, name: "test6", quantity: 1 },
{ id: 5, name: "test7", quantity: 1 },
{ id: 6, name: "test8", quantity: 1 }
];
var result = arr.reduce(function (r, a) {
r[a.id] = r[a.id] || { id: a.id, quantity: 0, name: a.name };
r[a.id].quantity += a.quantity;
return r;
}, Object.create(null));
console.log(JSON.stringify(result));
Using forEach loop and build object with aggregated quantity count.
const convert = (arr) => {
const res = {};
arr.forEach(({ id, ...rest }) =>
res[id] ? (res[id].quantity += 1) : (res[id] = { id, ...rest })
);
return Object.values(res);
};
const arr = [
{ id: 1, name: "test1", quantity: 1 },
{ id: 2, name: "test2", quantity: 1 },
{ id: 2, name: "test3", quantity: 1 },
{ id: 3, name: "test4", quantity: 1 },
{ id: 4, name: "test5", quantity: 1 },
{ id: 5, name: "test6", quantity: 1 },
{ id: 5, name: "test7", quantity: 1 },
{ id: 6, name: "test8", quantity: 1 },
];
console.log(convert(arr));
I am looking for a way to modify array of objects like this:
[
{
id: 1,
name: 'xyz',
count: 3,
},
{
id: 2,
name: 'aaa',
count: 2,
},
{
id: 6,
name: 'bbb',
count: 1,
},
]
Now I want to map it shomehow to receive new array of objects without count properties but with duplicated objects by its count value. We will have:
[
{
id: 1,
name: 'xyz',
},
{
id: 1,
name: 'xyz',
},
{
id: 1,
name: 'xyz',
},
{
id: 2,
name: 'aaa',
},
{
id: 2,
name: 'aaa',
},
{
id: 6,
name: 'bbb',
},
]
I tried to do it with map and reduce but it didn't work out as expected...
You could use a nested mapping with an outer Array#flatMap.
var data = [{ id: 1, name: 'xyz', count: 3 }, { id: 2, name: 'aaa', count: 2 }, { id: 6, name: 'bbb', count: 1 }],
result = data.flatMap(({ count, ...o }) =>
Array.from({ length: count }, _ => ({ ... o })));
console.log(result);
Nina Scholz solution works fine, if you want something easier to read:
var data = [{
id: 1,
name: 'xyz',
count: 3,
},
{
id: 2,
name: 'aaa',
count: 2,
},
{
id: 6,
name: 'bbb',
count: 1,
},
];
var output = [];
for (var i = 0; i < data.length; i++) {
var element = data[i];
for (var j = 0; j < element.count; j++) {
output.push({
id: element.id,
name: element.name
});
}
}
console.log(output);
I have an array of values: ["1", "2", "3"] which contains essentially the reference of the records stored in this array of object:
[
{ id: 1, name: "John" },
{ id: 2, name: "Patrick" },
{ id: 3, name: "Jack" },
{ id: 4, name: "Paula" },
{ id: 5, name: "Sarah" }
]
I would like to return the missing reference from the array of objects, so the result will be: 4, 5. What I achieved so far is takes all the selected values of the first array from all the select available in the html:
var selected_options = $('.options-picker')
.map(function() { return this.value}).get();
this will return 1, 2, 3. How can I extract from the array of objects 4, 5?
Thanks in advance.
Use filter and includes to check the object ids against the values in the array.
const data = [
{ id: 1, name: "John" },
{ id: 2, name: "Patrick" },
{ id: 3, name: "Jack" },
{ id: 4, name: "Paula" },
{ id: 5, name: "Sarah" }
];
const items = [1, 2, 3];
const out = data.filter(obj => !items.includes(obj.id));
console.log(out);
This will do
var a=[
{ id: 1, name: "John" },
{ id: 2, name: "Patrick" },
{ id: 3, name: "Jack" },
{ id: 4, name: "Paula" },
{ id: 5, name: "Sarah" }
]
var b=['1', '2', '3'];
a.forEach((e)=>{
if(b.indexOf(e.id.toString())==-1)
{
b.push(e.id);
}
})
alert(b)