Create multidemensional array, string and other array

Hey everyone,

I want to create a listbox where the user can select a chord shape.
Then i want to do some calcs with that selected item.

So i want to check that if the name of the selected item matches the name of an item in my array it should take the values of the array and do something with it.

What would be the best way to do this? Create a 2 dimensional array or use vector?

My array would look like this: a string and an array of ints. This should populate the listbox and then also be used for further calcs

1
2
3
4
5
 "min", {0,3,7}

"aug", {0,4,8}

"dim", {0,3,6}
I'd consider using a map with std::string being the key and std::vector being the value. Possibly:

 
std::map<std:string, std::vector<unsigned>> chord;


Perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <string>
#include <map>
#include <vector>
#include <iostream>

int main() {
	const std::map<std::string, std::vector<unsigned>> chords {{"min", {0, 3, 7}}, {"aug", {0, 4, 8}}, {"dim", {0, 3, 6}}};

	for (const auto& [name, values] : chords) {
		std::cout << name << "  ";

		for (const auto& v : values)
			std::cout << v << ' ';

		std::cout << '\n';
	}
}



aug  0 4 8
dim  0 3 6
min  0 3 7

Last edited on
dear seeplus,

Thank you!! I think map will be the way to go. I'm looking at the code from here:

https://github.com/BespokeSynth/BespokeSynth/blob/main/Source/ChordDatabase.cpp

I'm a c++ beginner, I think they build their own class in stead of a map, is that correct? I think the class is in the chorddatabase.h file
Last edited on
It's because in that code, they aren't looking up the chord's notes based on a map's key, rather they're figuring out the chord name based off the input notes. If we need to access it both ways, and the size of the list isn't absurdly large, then having a simple vector will be fine.
tx!
Is it possible that the for loop sorts automatically and if yes how can i turn that off? :)
Is it possible that the for loop sorts automatically

No. Using a std::map is where the sorting is happening.

If'n you don't want your content to be automatically sorted use a std::unordered_map.
https://en.cppreference.com/w/cpp/container/unordered_map
ok then it's random hmm, just find code of someone who wrote a fifo_map will try!
*Edit it works: if someone is interested: https://github.com/nlohmann/fifo_map
Last edited on
Ok, next item on the list :)

Is it possible to search this map by value? so I want to return {0, 4, 8} for example if i lookup the map using the "aug" value?
Similar to the example in the link you posted, you can access map["aug"] and map it to that {0, 4, 8} set of data.
And you can do a full iteration with
1
2
3
4
    for (auto x : m) {
        // x.first 
        // x.second
    }
Last edited on
You can search a map using a value rather than a key.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <string>
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>

using Notes = std::vector<unsigned>;

std::ostream& operator<<(std::ostream& os, const Notes& notes) {
	std::copy(notes.begin(), notes.end(), std::ostream_iterator<int>(os, " "));
	return os;
}

int main() {
	const std::map<std::string, Notes> chords {{"min", {0, 3, 7}}, {"aug", {0, 4, 8}}, {"dim", {0, 3, 6}}};

	bool fnd {};

	for (const auto& [nam, note] : chords)
		if (note == Notes {0, 4, 8}) {
			std::cout << nam << '\n';
			fnd = true;
			break;
		}

	if (!fnd)
		std::cout << "Not found\n";

	if (const auto itr {chords.find("dim")}; itr != chords.end())
		std::cout << itr->second << '\n';
	else
		std::cout << "Not found\n";
}



aug
0 3 6

Last edited on
great tx!!!
find code of someone who wrote a fifo_map

Use a std::queue that contains std::pair or std::tuple elements.
https://en.cppreference.com/w/cpp/container/queue
https://en.cppreference.com/w/cpp/utility/pair
https://en.cppreference.com/w/cpp/utility/tuple

Now you only deal with the last inserted element. Can't search through the container, though.

If you want to still be able to search the container use std::deque*.
https://en.cppreference.com/w/cpp/container/deque

Using a std::pair or std::tuple allows for searches based on any one of the contained data types.

*I might use a std::vector (my default choice for most uses) or maybe a std::list, depending on what the requirements are for dealing with the data. As well as the memory mapping of the elements.

Create the container and fill it with data one time and rarely if ever change the contents, std::vector. Dealing with constant insertions/deletions, I'd lean towards std::deque.

Learn what each C++ container can do, benefits and drawbacks, so choosing the proper one for a given task is easy.
#George P,

The fifo map works perfectly here and i can search my map, do you think i'll run into trouble using it?
Last edited on
@wimvandenborre Before you start coding your program, it's advisable to first design the program. In particular any algorithms to be used and data to be stored/manipulated. Once you know what data is to be stored, how it is to be manipulated and what questions are to be asked of the data, then you can make decisions as to how best the data can be stored - what containers, classes etc. Then only once you have a design do you then start to code from the design. Code in small parts and compile and test frequently. I used std::map above as an example, but in the full knowledge re usage etc this may not be the best.

According to Niklaus Wirth's famous equation:

Algorithms + Data Structures = Programs

If you can pick-up his 2 seminal books cheaply second hand, IMO they're well worth a read (although the code is based upon Pascal):

Algorithms Plus Data Structures Equals Programs
Systematic Programming: An Introduction
Last edited on
Ok thank you, will read up!
Topic archived. No new replies allowed.