JavaScript: How to Get the Values from a Multi-Dimensional Array? - javascript

I'm trying to get the values from a multi-dimensional array. This is what I have so far.
I need the value of 99 and the image when I select the first option in the array, e.g. "Billy Joel".
var concertArray = [
["Billy Joel", "99", "equal.png"],
["Bryan Adams", "89", "higher.png"],
["Brian Adams", "25", "lower.png"]
];
function populate(){
for(i = 0; i < concertArray.length; i++){
var select = document.getElementById("test");
select.options[select.options.length] = new Option(concertArray[i][0], concertArray[i][1]);
}
}

You can try to transform the multi-dimensional array to an array of objects like this:
var concertArray = [
{name: "Billy Joel", value: 99, image: "equal.png"},
{name: "Bryan Adams", value: 89, image: "higher.png"},
{name: "Brian Adams", value: 25, image: "lower.png"}
];
Then you can access the items in the array like regular objects:
var concertName = concertArray[0].name;
var concertPrice = parseFloat(concertArray[0].value);
var concertImage = concertArray[0].image;

let concertArray = [
["Billy Joel", "99", "equal.png"],
["Bryan Adams", "89", "higher.png"],
["Brian Adams", "25", "lower.png"]
];
let i = 0;
console.log(concertArray[i][1]) // 99
console.log(concertArray[i][2]) // equal.png

AFAIK, the Option constructor only takes two arguments, the text and the value. If you want to pass more data, I suggest you use the HTML5 data API:
var opt = new Option(concertArray[i][0], concertArray[i][1]);
opt.setAttribute('data-image', concertArray[i][2]);
select.options[select.options.length] = opt;
Then you can grab it using getAttribute('data-image')

You can access values by using 2 for loops as below.
var concertArray = [
["Billy Joel", "99", "equal.png"],
["Bryan Adams", "89", "higher.png"],
["Brian Adams", "25", "lower.png"]
];
function populate(){
for(i=0;i<arr.length;i++)
{
for(j=0;j<arr[i].length;j++)
{
console.log(arr[i][j]);
}
}
}

Related

Filter object array based on string array "with partial match"

I have an array of objects and want to filter it based on values of another string array and remove the objects that doesn't contain any of the strings.
I tried using split for the string array and search for each term in a forEach but it didn't work then tried the following which works as a filter but it filters for exact match not partial.
var employees = [
{"name": "zxc asd", "age":"30"},
{"name": "asd", "age":"24"},
{"name": "qwe", "age":"44"},
{"name": "zxc", "age":"28"},
];
var keepNames = ["asd", "qwe"];
keepNames = keepNames.map(name => {
return name.toLowerCase();
});
var filteredEmployees = employees.filter(emp => {
return keepNames.indexOf(emp.name.toLowerCase()) !== -1;
});
console.log( filteredEmployees );
Expected Output[
{"name": "zxc asd", "age":"30"},
{"name": "asd", "age":"24"},
{"name": "qwe", "age":"44"}];
Actual Output [
{"name": "asd", "age":"24"},
{"name": "qwe", "age":"44"}]
I'd really appreciate any help.
Thanks in advance
You need to iterate the array with names keep as well and check the value.
var employees = [{ name: "zxc asd", age: "30" }, { name: "asd", age: "24" }, { name: "qwe", age: "44" }, { name: "zxc", age: "28" }],
keep = ["asd", "qwe"],
filtered = employees.filter(({ name }) =>
keep.some(n => name.toLowerCase().includes(n))
);
console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }
indexOf uses strict equality so it won't match partially.
You can use some and includes
var employees = [ {"name": "zxc asd", "age":"30"},{"name": "asd", "age":"24"},{"name": "qwe", "age":"44"},{"name": "zxc", "age":"28"},];
var filterBy = ["asd", "qwe"];
var filteredEmployees = employees.filter(emp => {
return filterBy.some(v => emp.name.toLowerCase().includes(v.toLowerCase()))
});
console.log(filteredEmployees);

Sorting First Array With The Order Of Second Array

Suppose I am having two arrays namely namesArray and names as below
var namesArray = [{"name":"Charlie","age":3},{"name":"Dog","age":1},{"name":"Baker","age":7},{"name":"Abel","age":9}];
var names = ['Baker', 'Dog', 'Abel', 'Charlie'];
Can I achieve the following in UnderscoreJS so that sort the array named namesArray in a order so that all the name elements of namesArray will be in the same order of names .
In plain Javascript, you could use Array#sort with an object as reference for the sort order.
var namesArray = [{ "name": "Charlie", "age": 3 }, { "name": "Dog", "age": 1 }, { "name": "Baker", "age": 7 }, { "name": "Abel", "age": 9 }],
names = ['Baker', 'Dog', 'Abel', 'Charlie'],
hash = Object.create(null);
names.forEach(function (a, i) {
hash[a] = i + 1;
});
namesArray.sort(function (a, b) {
return (hash[a.name] || 0) - (hash[b.name] || 0);
});
console.log(namesArray);
Look up the index of each name in sort(). Not as performant as creating hash of indexes but chances are it's not that critical either
namesArray.sort(function(a,b){
return names.indexOf(a.name) - names.indexOf(b.name);
});
There is not lot to do with underscrore but you can do it like this:
I think using hash like what Nina does would be better than indexOf with respect to performance.
var namesArray = [{ "name": "Charlie", "age": 3 }, { "name": "Dog", "age": 1 }, { "name": "Baker", "age": 7 }, { "name": "Abel", "age": 9 }];
var names = ['Baker', 'Dog', 'Abel', 'Charlie'];
var sorted = _.sortBy(namesArray, o => names.indexOf(o.name));
console.log(sorted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>

Convert a two dimensional array into an array of objects

I have a two dimensional array, datas, that I want to convert to an array of objects.
The keys are in datas[0], I want to extract them, name, child, and size. and then append each attribute to it to get a master object. For some reason it overrides and is only showing one object when I try this?
var test = new Object();
for (i = 0; i < datas.length; i++){
var obj = new Object();
obj.name = datas[i][0];
obj.parent = datas[i][1];
obj.size = datas[i][2];
test.update(obj);
}
I would like the final result to be:
[
{"name": "Billy", "parent":"Ann", "size": "1"},
{"name": "Ben", "parent": "John", "size": "1"},
etc...
]
The datas array looks like:
[["Name", "Parent", "Size"], ["Billy", "Ann", "1"], ["Ben", "John", "1"] ... ]
You can't make an object without properties, so your desired result can't be achieved.
Assuming you want:
[
{"name": "Billy", "parent": "Ann", "size": "1"},
{"name": "Ben", "parent": "John", "size": "1"},
etc...
]
Try:
var test = [];
for(i = 0; i < datas.length; i++){
test.push({
name: datas[i][0],
parent: datas[i][1],
size: datas[i][2]
});
}
// do something with test
{
{"name": "Billy", "parent":"Ann", "size"="1"},
{"name": "Ben", "parent": "John", "size" = "1"}
}
is not correct json. curly braces mean - object, object must be presented in key:value form. There are two possible correct json of this kind:
array of objects
[
{"name": "Billy", "parent":"Ann", "size"="1"},
{"name": "Ben", "parent": "John", "size" = "1"}
]
deep structure
{
"Billy" {"parent":"Ann", "size"="1"},
"Ben" {"parent": "John", "size" = "1"}
}
to generate first variant
var res = []
for(i = 0; i<datas.length; i++){
var obj = new Object();
obj.name = datas[i][0];
obj.parent = datas[i][1];
obj.size = datas[i][2];
res.push(obj);
}
JSON.stringify(res);
to generate second variant
var res = new Object();
for(i = 0; i<datas.length; i++){
var obj = new Object();
obj.parent = datas[i][1];
obj.size = datas[i][2];
res.[datas[i][0]] = obj;
}
JSON.stringify(res);

Restructure / rebuild json data tree

{
"company": [
{ "region": [ "Europe", "Germany" ], "productLine": "Produce" },
{ "region": [ "Europe", "France" ], "productLine": "Produce" }
],
"company2": [
{ "region": [ "Europe", "Germany" ], "productLine": "Produce" },
{ "region": [ "Americas", "USA" ], "productLine": "Produce" }
]
}
With this json data how can I rebuild it so that I have Europe/Americas value as the primary(unique) node with Germany/France as it's children? company/company1 would be sub-children of France/Germany. I cant seem to figure out how to build arrays while keeping the relations correct. I essence I need to reverse the node tree.
Expected Output:
Tree structure like this:
-Europe
-France
-Company
-Company2
I also need a special structure for a tree plugin:
var source = [ { label: "Europe", items: [
{label: "France", items: [
{label: "SuperShop", items: [
{label: "Produce"}
]}
]
}]
}]
What I need in the end is an Object array with value pair: label, items. Items being an object with sub-objects within.
Obviously, I don't know why you need the new format, but it seems overly complex. If you have a large data set that you are looking through, you are going to take a hit on speed because, under it's current set up, you are going to have traverse over every element of the new array to find the one you are looking for ...
var inputs = {
"company": [
{ "region": [ "Europe", "Germany" ], "productLine": "Produce" },
{ "region": [ "Europe", "France" ], "productLine": "Produce" }
],
"company2": [
{ "region": [ "Europe", "Germany" ], "productLine": "Produce" },
{ "region": [ "Americas", "USA" ], "productLine": "Produce" }
]
};
var converter = {};
// This new format requires a 2 step process to prevent it from being N^2
// So convert the input into a tree
// Region
// -> Country
// -> Company
// -> Array of Products
for(var company in inputs){
for(var i = 0; i < inputs[company].length; i++){
// Because the regions are an array of hashes it is simplest
// to grab the value by using the previously gathered keys
// and the key region
var r = inputs[company][i]['region'];
// Check if the region exists. If not create it.
if(!converter[r[0]]){
converter[r[0]] = {};
}
// Check if the country exists. If not create it.
if(!converter[r[0]][r[1]]){
converter[r[0]][r[1]] = {};
}
// Add the company to the array.
if(!converter[r[0]][r[1]][company]){
converter[r[0]][r[1]][company] = [];
}
converter[r[0]][r[1]][company].push(inputs[company][i]['productLine']);
}
}
var outputs = [];
// Now walk converter and generate the desired object.
for( var region in converter){
converted_region = {};
converted_region["label"] = region;
converted_region["items"] = [];
for( var country in converter[region]){
converted_country = {};
converted_country["label"] = country;
converted_country["items"] = [];
for( var company in converter[region][country]){
converted_company = {};
converted_company["label"] = company;
converted_company["items"] = [];
for(var i = 0; i < converter[region][country][company].length; i++){
converted_company["items"].push(converter[region][country][company][i]);
}
converted_country["items"].push(converted_company);
}
converted_region["items"].push(converted_country);
}
outputs.push(converted_region);
}

Remove an item from an array by value

I have an array of items like:
var items = [id: "animal", type: "cat", cute: "yes"]
And I'm trying to remove any items that match the ID given. In this case; animal
I'm stuck! I can get it to work easily by having a more simpler array but this is not what I need... I also need to remove the item by value as I don't want the hassle of referring to items by their index.
Is there a jQuery method I could use where I don't need to iterate through the items array, rather specify a selector?
Here is my jsFiddle: http://jsfiddle.net/zafrX/
I'm not sure how much of a hassle it is to refer to array items by index. The standard way to remove array items is with the splice method
for (var i = 0; i < items.length; i++)
if (items[i] === "animal") {
items.splice(i, 1);
break;
}
And of course you can generalize this into a helper function so you don't have to duplicate this everywhere.
EDIT
I just noticed this incorrect syntax:
var items = [id: "animal", type: "cat", cute: "yes"]
Did you want something like this:
var items = [ {id: "animal", type: "cat", cute: "yes"}, {id: "mouse", type: "rodent", cute: "no"}];
That would change the removal code to this:
for (var i = 0; i < items.length; i++)
if (items[i].id && items[i].id === "animal") {
items.splice(i, 1);
break;
}
No need for jQuery or any third party lib for this, now we can use the new ES5 filter :
let myArray = [{ id : 'a1', name : 'Rabbit'}, { id : 'a2', name : 'Cat'}];
myArray = myArray.filter(i => i.id !== 'a1');
You can either use splice or run a delete yourself. Here's an example:
for (var i = 0; i < items.length; i ++) {
if (items[i] == "animal") {
items.splice(i, 1);
break;
}
}
There's a simple way!
myItems.splice(myItems.indexOf(myItems.find(row => row.id == id)), 1);
Demo below:
// define function
function delete_by_id(id) {
var myItems = [{
id: 1,
type: "cat",
cute: "yes"
}, {
id: 2,
type: "rat",
cute: "yes"
}, {
id: 3,
type: "mouse",
cute: "yes"
}];
// before
console.log(myItems);
myItems.splice(myItems.indexOf(myItems.find(item => item.id == id)), 1);
// after
console.log(myItems);
}
// call function
delete_by_id(1);
You should do it like this (make sure that you have the right syntax...you cannot have array with properties, but object inside {} and then you can iterate by keys and delete unwanted key):
var items = {id: "animal", type: "cat", cute: "yes"}
var removeItem = "animal"; // or with the ID matching animal...
for(var p in items){
if(items[p] === removeItem)
delete items[p]
}
And to answer you question, you cannot apply jquery selectors to javascript objects. The best you can do to avoid for loop is to use $.each (which is a loop written in a more "functional" way).
By using object notation : http://jsfiddle.net/jrm2k6/zafrX/2/
var animal1 = {id: "animal", type: "cat", cute: "yes"}
var car2 = {id: "car", type: "pick-up", cute: "no"}
var animal3 = {id: "animal", type: "dog", cute: "yes"}
var removeItem = "animal"; // or with the ID matching animal...
var array_items = []
array_items.push(animal1);
array_items.push(car2);
array_items.push(animal3);
for(var i=0;i<array_items.length;i++){
if(array_items[i].id == removeItem){
array_items.splice(i,1);
}
}
//alert(array_items.length);
Wow, so many ideas but still not what I wanted xD
This will remove ALL entries of the given value and return the removed value:
function removeOfArray(val, arr){
var idx;
var ret;
while ((idx = arr.indexOf(val)) > -1){
arr.splice(idx, 1);
ret = val;
}
return ret;
}
Also I found other solutions here:
Remove item from array by value
-parray : list of array of object
-pstring :value to remove from the array
-ptag :using which tag we
function removeFromArr (parray,ptag,pstring){
var b =[];
var count = 0;
for (var i =0;i<parray.length;i++){
if(pstring != parray[i][ptag]){
b[count] = parray[i];
count++;
}
}
return b;
}
var lobj = [ {
"SCHEME_CODE": "MIP65",
"YEARS": "1",
"CURRENCY": "GBP",
"MAX_AMT": 200000,
"MIN_AMT": 1000,
"AER_IR": "1.80",
"FREQUENCY": "Monthly",
"CUST_TYPE": "RETAIL",
"GROSS_IR": "1.79"
},
{
"SCHEME_CODE": "MIP65",
"YEARS": "2",
"CURRENCY": "GBP",
"MAX_AMT": 200000,
"MIN_AMT": 1000,
"AER_IR": "1.98",
"FREQUENCY": "Monthly",
"CUST_TYPE": "RETAIL",
"GROSS_IR": "1.96"
},
{
"SCHEME_CODE": "MIP65",
"YEARS": "3",
"CURRENCY": "GBP",
"MAX_AMT": 200000,
"MIN_AMT": 1000,
"AER_IR": "2.05",
"FREQUENCY": "Monthly",
"CUST_TYPE": "RETAIL",
"GROSS_IR": "2.03"
},
{
"SCHEME_CODE": "MIP65",
"YEARS": "5",
"CURRENCY": "GBP",
"MAX_AMT": 200000,
"MIN_AMT": 1000,
"AER_IR": "2.26",
"FREQUENCY": "Monthly",
"CUST_TYPE": "RETAIL",
"GROSS_IR": "2.24"
},
{
"SCHEME_CODE": "QIP65",
"YEARS": "1",
"CURRENCY": "GBP",
"MAX_AMT": 200000,
"MIN_AMT": 1000,
"AER_IR": "1.80",
"FREQUENCY": "Quarterly",
"CUST_TYPE": "RETAIL",
"GROSS_IR": "1.79"
},
{
"SCHEME_CODE": "QIP65",
"YEARS": "2",
"CURRENCY": "GBP",
"MAX_AMT": 200000,
"MIN_AMT": 1000,
"AER_IR": "1.98",
"FREQUENCY": "Quarterly",
"CUST_TYPE": "RETAIL",
"GROSS_IR": "1.97"
},
]
function myFunction(){
var final = removeFromArr(lobj,"SCHEME_CODE","MIP65");
console.log(final);
}
<html>
<button onclick="myFunction()">Click me</button>
</html>
are going to remove from the objects
function removeFromArr(parray, pstring, ptag) {
var farr = [];
var count = 0;
for (var i = 0; i < pa.length; i++) {
if (pstring != pa[i][ptag]) {
farr[count] = pa[i];
count++;
}
}
return farr;
}
ES6 Solution
persons.splice(persons.findIndex((pm) => pm.id === personToDelete.id), 1);

Categories

Resources