I just want to delete the specTplItemDropped() function parameter item from this data structure:
this.areas:
items:
item:
code:
public specTplItemDropped(index, item, external, type, area1) {
let newArray = this.areas.map(areaV => {
let a = areaV.items.filter(itemV => {
let b = itemV.id !== item.id;
return b;
});
return a;
});
console.log(newArray);
The new array should be the same as the old array, minus one item. But it is very different:
What am I doing wrong?
The input is an array of objects, but you're returning an array rather than an object from the .map() call. You need to return a copy of the original object, with the new array of items.
function specTplItemDropped(index, item, external, type, area1) {
let newArray = this.areas.map(areaV => {
let a = areaV.items.filter(itemV => {
let b = itemV.id !== item.id;
return b;
});
return Object.assign({items: a, itemCount: a.length}, areaV);
});
console.log(newArray);
}
Related
I have a function
checkName(output) {
output.filter((NewData) => {
return this.props.elements.filter((OldData) => {
if (NewData.key == OldData.key) {
NewData.name = OldData.name,
//there i need to add another element
// Need to add newData.number = OldData.number
}
return NewData
})
})
return output
}
and I call this function like:
const named = this.checkName(product.rows)
Now I need to add to my product's array that I passed to checkName the value "OldData.Number" to "newData.Number" that is not defined in product (so I need to create this field)
For example:
Product before the checkName function
product.rows = [NewData.name]
Product after the checkName function
product.rows = [NewData.name="value of OldData.name", NewData.number="value of OldData.number"]
How can I obtain this result?
There are 2 confusing things in your code:
You are using filter to execute an action in each member of the output array. However, filter should be used to... well, filter that array, meaning that is should not modify it, just return a sub-set of it. Instead, you might want to use forEach. However, taking into accound the next bullet, probably you want to use map.
You are modifying the array passed to the checkName function. This is confusing and can lead to hard-to-find bugs. Instead, make your function "pure", meaning that it should not mutate its inputs, instead just return the data you need from it.
I would suggest some implementation like this one:
checkName(output){
return output.map((NewData) => {
// find the old data item corresponding to the current NewData
const OldData = this.props.elements.find(x => x.key === NewData.key);
if (OldData) {
// If found, return a clone of the new data with the old data name
// This uses the spread syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
return {
...NewData, // Clone the NewData object
name: OldData.name, // set the value found in OldData.name in the "name" field of the cloned object
number: OldData.number, // You can do the same for each field for which you want to replace the value cloned from NewValue
};
} else {
// Otherwise, just return a clone of the NewData
return { ...NewData };
}
}
}
The usage would be like this:
const named = this.checkName(product.rows)
Be aware that the product.rows array won't be modified!
You can get keys and values of the old object.
const keys = Object.keys(oldObject);
const values = Object.values(oldObject);
// or
const [keys, values] = Object.entries(oldObject);
After, you will create a loop with all keys of oldObject, and insert in newObject like a array.
keys.forEach( (key, index) => newObject[key] = values[index]);
// or
for (const [key, value] of Object.entries(object1)) {
newObject[key] = value
}
Use map like this.
checkName(output){
return output.map(( NewData) =>{
this.props.elements.forEach((OldData) => {
if (NewData.key == OldData.key) {
NewData.name = OldData.name;
NewData.number = OldData.number;
}
})
return NewData;
})
// return output;
}
const addLast = (element) => {
return (arr) => {
};
};
Add an element at the back of the array.
Arguments
element (any): The element to add.
Returns
(Array) => Array: Returns a closure that will create a copy of the array with the new element at back.
If I understood correctly what you want, try this:
const addLast = (element) => {
return (arr) =>{
let array = arr.slice(1,arr.length);
array.push(element);
return array;
}
}
I want to return an array of ids, but the whole object is being returned.
Do I have the correct syntax?
const docIds = this.claim.claimDocuments.filter(doc => {
if (doc.status !== 'Submitted') {
return doc.id;
}
});
filter doesn't change the array, it just selects the entries which pass the logical test. You then need to map the output of filter to return only the id values:
const docIds = this.claim.claimDocuments
.filter(doc => doc.status !== 'Submitted')
.map(doc => doc.id);
If you want to create an array from a portion of items in another while also transforming each passing item into something else, you'll have to use a different method, perhaps by initializing the array, then pushing inside the if while iterating:
const docIds = [];
for (const doc of this.claim.claimDocuments) {
if (doc.status !== 'Submitted') {
docIds.push(doc.id);
}
}
Or with .reduce:
const docIds = this.claim.claimDocuments.reduce((a, doc) => {
if (doc.status !== 'Submitted') {
a.push(doc.id);
}
return a;
}, []);
Or with .filter followed by .map, though this requires iterating over some items twice.
Shouldn't this be creating a new dictionary and be able to replace its values everytime I call the getVal function?
var dict = [];
function getVal(inarr, element, data) {
var arr = inarr[element].map((item) => item[data]);
return arr;
};
console.log(getVal(event, 'foo', 'bar'));
function getVal(inarr, element, data) {
var arr = inarr[element].map((item) => item[data]);
return arr;
};
console.log(getVal(event, 'foo', 'bar'));
It's guess work at best because your question isn't clear and input is missing but you could try something like this:
//keys is an array of string or function
// if it's a function then it will pass current object
// to that function
function getMember(object,keys){
return keys.reduce(
function(acc,key){
if(acc===undefined){
return acc;
}
if(typeof key === "function"){
return key(acc);
}
return acc[key];
}
,object
)
}
function getVal(object) {
return getMember(
object,
[
"foo", // get member foo is an array of {bar:number}
function(x){ //map array of {bar:number} to array of number
return x.map(
function(x){
return x.bar;
});
}
]
);
};
var event = {
foo:[
{
bar:1
},
{
bar:2
}
]
};
console.log(getVal(event));// should log [1,2]
I trying to show a message in an array is empty in a filter method in Vue.
However, it seems my computed function still returns an array of empty object (If I search for something not there)
What I wish is that it only returns the object that actually has a value - the empty ones should be filtered out?
So if I search for "fjhdsfjsdfjsd" ex, it still return about 200 items, just empty objects, which it shouldnt?
The computed function looks like:
filteredAlarms: function () {
let filter = {};
let searchString = this.search_string.toLowerCase();
Object.keys(this.eventLog).forEach(key => {
filter[key] = this.eventLog[key].filter(item => {
let systemName = item.system_name.toLowerCase();
if(item.type.includes("alarm") && systemName.includes(searchString)) {
return item;
}
});
});
return filter
},
Array.prototype.filter must return a boolean. Just remove the if and the return item part and just return your if condition:
filteredAlarms: function () {
let searchString = this.search_string.toLowerCase();
let eventKeys = Object.keys(this.eventLog);
return eventKeys.reduce((filter, key) => {
let items = this.eventLog[key].filter(item => {
let systemName = item.system_name.toLowerCase();
return item.type.includes("alarm") && systemName.includes(searchString);
});
return Object.assign(filter, { [key]: items });
}, {});
}
Try this one. I hope this will work.
filteredAlarms: function () {
let filter = {};
let searchString = this.search_string.toLowerCase();
Object.keys(this.eventLog).forEach(key => {
filter[key] = this.eventLog[key].filter(function(item){
return item.type.includes("alarm") && item.system_name.toLowerCase().includes(searchString);
});
});
return filter
},