I have an array of arrays of data returning to me back from a csv file. I am attempting to filter out each index of an array depending on which title is in the array. For example:
If an index of the array has the name "Retail" return that entire index which includes some values.
Here is my array :
[
[
"Retail",
"22,477",
"24,549",
"19,580",
"15,358",
],
[
"Online",
"8,653",
"7,586",
"2,432",
"4,321"
],
[
"In Store",
"2,532",
"2,836",
"5,632",
"7,325"
]
]
I've attempted these two separate ways and both are returning an array of 0:
filtArr = dataList.filter(name => name.includes('Retail')) //expecting the array length 5 with "Retail" and it's values
attempt 2
filtArr = dataList.filter(function (name) {
return (name === "Retail")
})
Expected return is: console.log(filtArr) // [ 0. "Retail", 1. "22,477", 2. "24,549", 3. "19,580", 4. "15,358"
A good way to check if an array contains some item is to test it with the indexOf method.
It will return -1 if the item is not found or else its index.
You could do this to store all arrays containing 'Retail' in them:
let retailArrays = [];
arrayOfArrays.forEach(
array => {
if( array.indexOf('Retail') !== -1) {
retailArrays.push(array);
};
}
)
You apparently have trailing spaces after some of the names, so maybe "Retail" is actually "Retail ".
It also looks like the name is always the first element of the nested array, so there's no need to search the whole array.
So use trim() on the first element to remove the surrounding spaces.
filtArr = dataList.filter(arr => arr[0].trim() == 'Retail');
var dataList = [
[
"Retail",
"22,477",
"24,549",
"19,580",
"15,358",
],
[
"Online",
"8,653",
"7,586",
"2,432",
"4,321"
],
[
"In Store",
"2,532",
"2,836",
"5,632",
"7,325"
]
];
filtArr = dataList.filter(arr => arr[0].trim() == 'Retail');
console.log(filtArr);
Related
I want to loop through 600+ array items in an object and find one particular item based on certain criteria. The array in the object is called "operations" and its items are arrays themselves.
My goal is to get the index of operation's array item which has the deeply nested string "Go".
In the sample below this would be the first element. My problem is that I can check if an array element contains "call" and "draw" but I don't know how to test for the nested dictionary "foobar". I only have basic JavaScript available, no special libraries.
let json = {
"head": {},
"operations": [
[
"call",
"w40",
"draw",
{
"parent": "w39",
"style": [
"PUSH"
],
"index": 0,
"text": "Modify"
}
],
[
"call",
"w83.gc",
"draw",
{
"foobar": [
["beginPath"],
[
"rect",
0,
0,
245,
80
],
["fill"],
[
"fillText",
"Go",
123,
24
],
[
"drawImage",
"rwt-resources/c8af.png",
]
]
}
],
[
"create",
"w39",
"rwt.widgets.Menu",
{
"parent": "w35",
"style": [
"POP_UP"
]
}
],
[
"call",
"w39",
"draw",
{
"parent": "w35",
"style": [
"POP_UP"
]
}
]
]
};
let index = "";
let operationList = json.operations;
for (i = 0; i < operationList.length; i++) {
if (operationList[i].includes('call') && operationList[i].includes('draw')) //missing another check if the dictionary "foobar" exists in this element )
{
index = i;
}
}
document.write(index)
I'll preface by saying that this data structure is going to be tough to manage in general. I would suggest a scheme for where an operation is an object with well defined properties, rather than just an "array of stuff".
That said, you can use recursion to search the array.
If any value in the array is another array, continue with the next level of recursion
If any value is an object, search its values
const isPlainObject = require('is-plain-object');
const containsTerm = (value, term) => {
// if value is an object, search its values
if (isPlainObject(value)) {
value = Object.values(value);
}
// if value is an array, search within it
if (Array.isArray(value)) {
return value.find((element) => {
return containsTerm(element, term);
});
}
// otherwise, value is a primitive, so check if it matches
return value === term;
};
const index = object.operations.findIndex((operation) => {
return containsTerm(operation, 'Go');
});
Are the steps I'm taking to solve this problem correct?
I'm working on turning a data structure of an array of arrays such as
this.arrayofAnimalsAndValues = [
[ "Ant", 1287, 12956],
[ "Lion", 2574, 25826],
[ "Bear", 3861, 38696],
.....
]
into this
this.jsonOfAnimalsAndValues = [
{category: "Ant", value_1: 1287, value_2:12956},
{category: "Lion", value_1: 2574, value_2:25826},
{category: "Bear", value_1: 3861, value_2:38696},
.....
]
where the first item in the array is always assigned to 'category' in the array object and the following items assigned to value_# depending on their order in the array. So the 2nd array item would have key value_1 and so on. For example, for 1 nested array:
[[ "Ant", 5148, 51566]] to =>
[{category: "Ant", value_1: "5148", value_2: 51566}]
I've created a hardcoded way to achieve this however I'm trying to make it dynamic:
'hardcoded' way:
this.variableOfKeys = ["value_1", "value_2", "value_3", ......]
this.jsonOfAnimalsAndValues = this.arrayofAnimalsAndValues(function(x) {
return {
category: x[0],
no1: x[1],
no2: x[2],
.....
};
});
where I just hardcode the keys and their values (values using their index).
My attempt to make it dynamic:
this.variableOfKeys.forEach(element => {
this.jsonOfAnimalsAndValues = this.arrayofAnimalsAndValues.map(function(x) {
for (var i = 0; i<=this.arrayOfValuesToUseAsKeys.length; ++i) {
return {
category: x[0],
element: x[i+1],
};
}
});
});
where my logic is that for each item in
this.variableOfKeys = ["value_1", "value_2", "value_3", ......],
I created this.jsonOfAnimalsAndValues such that the first item (item with the 0th index) in the array this.arrayofAnimalsAndValues is assigned to the key category and the following items (depending on their index) are assigned to the values in this.variableOfKeys in order starting from no1, then no2 etc.
However, I don't think this is written correctly and I keep getting this error:
"TypeError: Cannot read property 'variableOfKeys' of undefined"
Can I ask how it might be written incorrectly and so how I might be able to create this.jsonOfAnimalsAndValues from this.arrayofAnimalsAndValues?
You can map each subarray to an array of entries, then turn it into an object to return with Object.fromEntries:
const arrayofAnimalsAndValues = [
[ "Ant", 1287, 12956],
[ "Lion", 2574, 25826],
[ "Bear", 3861, 38696],
];
const output = arrayofAnimalsAndValues.map(
([category, ...rest]) => Object.fromEntries([
['category', category],
...rest.map((value, i) => ['value_' + (i + 1), value])
])
);
console.log(output);
Given an array of the keys you can map() the main array and use reduce() on each subarray to generate each object
const arr=[["Ant",1287,12956],["Lion",2574,25826],["Bear",3861,38696]],
keys = ['category','value_1','value_2'];
const res = arr.map(e => e.reduce((a,c,i) => (a[keys[i]] = c, a),{}))
console.log(res)
.as-console-wrapper { max-height: 100%!important;top:0}
I've array like this
const data: { "status" : ["aa","bb","cc","dd"],
["ee","ff","gg","hh"],
["ii","jj","kk","ll"] }
const value=2;
and another array like this
const array2: { "name":"status", "data": ["cc","gg"] }
I want to convert array1 into this
const data: "status" : ["aa","bb","cc","dd"],
["ee","ff","gg","hh"]
here Value is the index where I get the data which I have to filter from second array.
and in array1, data has the key value pair where status is the key and value is the array
I use the filter method. but I'm not able to travel through status to filter the array.
P.S. thank you in advance
I'm not positive if this is what you are asking for, but it seems like you're wanting to trim the arrays of data.status to only the ones that contain at least one of the values in array2.data.
To check this, in your filter you can use the some array method and check if each element is included in array2.data.
const data = {
"status": [
["aa", "bb", "cc", "dd"],
["ee", "ff", "gg", "hh"],
["ii", "jj", "kk", "ll"]
]
}
const array2 = {
"name": "status",
"data": ["cc", "gg"]
}
console.log('Before')
console.log(data.status)
data.status = data.status.filter(row => row.some(elem => array2.data.includes(elem)))
console.log('After')
console.log(data.status)
I have a store that looks like this, 3 objects within an array that carry array. How can I add an object in between the first and second object that carry index 1 and 2?
{
object: [
{
"index": 1,
"title": "title",
"caption": "caption",
},
{
"index": 2,
"title": "title",
"caption": "caption",
},
{
"index": 3,
"title": "title",
"caption": "caption",
},
]
}
Would like to have the final output like this after clicking a button that pass in the index value of 1.
{
object: [
{
"index": 1,
"title": "title",
"caption": "caption",
},
{
"index": 2,
"title": "NEW",
"caption": "NEW",
},
{
"index": 3,
"title": "title",
"caption": "caption",
},
{
"index": 4,
"title": "title",
"caption": "caption",
},
]
}
I can use the following codes to change the index value through action, but how to add another new object in between object 1 and object 2, plus changing the index value at the same time?
switch (action.type) {
case ADDCOMPONENT:
return {
...state,
object: state.object.map(component =>
(component.index > action.index ?
{ ...component, index: component.index + 1 } : component)),
};
smth.object.splice(index, 0, item);
And don't keep item index as a string. You can easily get position of item in array, and then add 1 to the value
state.object.splice(component.index, 0, component);
should do the trick
The other answers seem to miss the point that you need to increment the indexes of the other objects in the array. I'd approach it in two steps: first adding the new object with splice, then looping through and incrementing all subsequent indexes.
var index = 1;
state.object.splice(index, 0, new_component); //Insert the new object
//Starting where you inserted, add one to all later components
for (var i = index +1; i < state.object.length; i++) {
state.object[i].index ++;
}
After this state holds the value you want.
However, I'd encourage you to think about if the objects really need to know where they are in the array. In my experience, any code that would need to access the objects would be able to tell where they are in the array.
The shape of your store is created by the combination of all your reducers. The data that you want to update your store with should be created in your application and then sent to your reducer with dispatch(action). The reducer takes the information on the action and updates your state accordingly. If you want to add an object into an array you can use Array.prototype.splice() as follows: myArray.splice( startIndex, 0, itemsToInsert, ... ).
In short, don't add the object in your reducer. Add it to the data you are sending in your action, before you send the action.
If you would like to be able to insert things into an array and not mutate them, you should think about using a function like the one in this snippet:
function nonMutatingArrayInsert( array, index, insert ) {
// return array if index is outside range of array
if ( index < 0 || index > array.length - 1 ) return array;
// ensure insert is array for concat purposes
let _insert = Array.isArray( insert ) ? insert : [ insert ];
// handle 0 index insert
if ( index === 0 ) { return [ ..._insert, ...array ]; }
// handle end of array insert
if ( index === array.length ) { return [ ...array, ..._insert ] }
// handle everyhing else
const before = array.slice( 0, index );
const after = array.slice( index, array.length );
// return new non-mutated array
return [ ...before, ..._insert, ...after ];
}
let myArray = [ "one", "four" ];
let newArray = nonMutatingArrayInsert( myArray, 1, ["two", "three"] );
console.log( "myArray:\n", myArray );
console.log( "newArray:\n", newArray );
All the answers works, however in order to not mutate the array, I have used the following codes instead.
Slice the array before and insert the new object in between.
let newObject = state.portfolio.components.slice(0, action.index);
newObject = newObject.concat(NEWOBJECT);
newObject = newObject.concat(state.portfolio.components.slice(action.index));
for (let i = action.index; i < newComponent.length; i++) {
newComponent[i].index = i + 1;
}
Replace the object with the newObject.
switch (action.type) {
case ADDCOMPONENT:
return {
...state,
object: newObject,
};
EDITED: Used immutability-helper in the end with simpler codes without mutating.
return update(state, {
portfolio: {
object: {
$splice: [
[action.index + 1, 0, action.newObject],
],
},
}
});
I push in values from JSON into a several arrays using Underscore, but I want to eliminate any repeated values if there are any, either during push or after. How could I do this?
JSON
looks = [{
"id": "look1",
"products": ["hbeu50271385", "hbeu50274296", "hbeu50272359", "hbeu50272802"]
}, {
"id": "look2",
"products": [
"hbeu50274106", "hbeu50273647", "hbeu50274754", "hbeu50274063", "hbeu50274911", "hbeu50274106", "hbeu50240022", "hbeu50271944"
]
}, {
"id": "look3",
"products": [
"hbeu50272935", "hbeu50274426", "hbeu50271624", "hbeu50274762", "hbeu50275366", "hbeu50274433", "hbeu50262002", "hbeu50272364", "hbeu50272359"
]
}
.......
]
JS (Underscore)
var productArrays = [];
_.each(looks, function(look) {
var productArray = [];
_.each(look.products, function(product) {
productArray.push(product.replace(/_.*/, ''))
})
productArrays.push(productArray);
});
There are couple ways
1.Use _.uniq
_.uniq(productArray);
2.Use _.indexOf before push to productArray
Example
For array's content be unique, how about using _.uniq?
Or just check existence of value before really push it.
function uniquePush(arr, valueToPush) {
if(arr.indexOf(valueToPush) == -1) {
arr.push(valueToPush)
}
}